Changeset 671
- Timestamp:
- 09/07/08 16:11:40 (3 months ago)
- Files:
-
- trunk/as3/lib/com/modestmaps/core/MapExtent.as (modified) (1 diff)
- trunk/as3/lib/com/modestmaps/core/MarkerClip.as (modified) (12 diffs)
- trunk/as3/lib/com/modestmaps/core/PolygonClip.as (modified) (3 diffs)
- trunk/as3/lib/com/modestmaps/core/PolygonMarker.as (modified) (3 diffs)
- trunk/as3/lib/com/modestmaps/core/Redrawable.as (added)
- trunk/as3/lib/com/modestmaps/core/TileGrid.as (modified) (5 diffs)
- trunk/as3/swc/bin/ModestMapsSWC.swc (modified) (previous)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/as3/lib/com/modestmaps/core/MapExtent.as
r670 r671 165 165 return extent; 166 166 } 167 168 public static function fromLocation(location:Location):MapExtent 169 { 170 return new MapExtent(location.lat, location.lat, location.lon, location.lon); 171 } 172 167 173 168 174 public static function fromLocationProperties(objects:Array, locationProp:String='location'):MapExtent trunk/as3/lib/com/modestmaps/core/MarkerClip.as
r670 r671 18 18 import flash.geom.Point; 19 19 import flash.utils.Dictionary; 20 import flash.utils.clearTimeout; 21 import flash.utils.getTimer; 22 import flash.utils.setTimeout; 20 23 21 24 [Event(name="markerRollOver", type="com.modestmaps.events.MarkerEvent")] … … 24 27 public class MarkerClip extends Sprite 25 28 { 26 // TODO: mask me?27 29 protected var map:Map; 28 protected var starting:Point; 30 31 protected var drawCoord:Coordinate; 32 29 33 protected var locations:Dictionary = new Dictionary(); 30 34 protected var coordinates:Dictionary = new Dictionary(); … … 34 38 // enable this if you want intermediate zooming steps to 35 39 // stretch your graphics instead of reprojecting the points 40 // it's useful for polygons, but for points 36 41 // it looks worse and probably isn't faster, but there it is :) 37 42 public var scaleZoom:Boolean = false; … … 75 80 this.x = map.getWidth() / 2; 76 81 this.y = map.getHeight() / 2; 77 82 83 drawCoord = map.grid.centerCoordinate.copy(); 84 78 85 previousGeometry = map.getMapProvider().geometry(); 79 86 80 map.addEventListener(MapEvent.START_ZOOMING, onMapStartZooming);87 map.addEventListener(MapEvent.START_ZOOMING, onMapStartZooming); 81 88 map.addEventListener(MapEvent.STOP_ZOOMING, onMapStopZooming); 82 89 map.addEventListener(MapEvent.ZOOMED_BY, onMapZoomedBy); … … 195 202 } 196 203 204 private var sortTimer:uint; 205 197 206 public function updateClips(event:Event=null):void 198 207 { … … 201 210 } 202 211 212 var center:Coordinate = map.grid.centerCoordinate; 213 214 if (center.equalTo(drawCoord)) { 215 dirty = false; 216 return; 217 } 218 219 drawCoord = center.copy(); 220 221 this.x = map.getWidth() / 2; 222 this.y = map.getHeight() / 2; 223 224 if (scaleZoom) { 225 scaleX = scaleY = 1.0; 226 } 227 203 228 var marker:DisplayObject; 204 229 205 //var t:int = flash.utils.getTimer();206 230 var doSort:Boolean = false; 207 231 for each (marker in markers) … … 210 234 } 211 235 212 if (doSort) sortMarkers(true); 236 if (doSort) { 237 // use a timer so we don't do this every single frame 238 // sorting markers and applying depths pretty much doubles the time to update 239 if (sortTimer) { 240 clearTimeout(sortTimer); 241 } 242 sortTimer = setTimeout(sortMarkers, 100, true); 243 } 213 244 214 245 dirty = false; 215 //trace("reprojected all markers in " + (flash.utils.getTimer() - t) + "ms");216 246 } 217 247 … … 225 255 coordinates[marker] = provider.locationCoordinate(locations[marker]); 226 256 } 257 dirty = true; 227 258 } 228 259 … … 278 309 return false; 279 310 } 280 281 protected function onMapStartPanning(event:MapEvent):void 282 { 283 starting = new Point(x, y); 311 312 ///// Events.... 313 314 protected function onMapExtentChanged(event:MapEvent):void 315 { 316 onMapZoomedBy(event); 317 onMapPanned(event); 284 318 } 285 319 286 320 protected function onMapPanned(event:MapEvent):void 287 321 { 288 if (map.grid.panning && map.grid.zooming) { 289 // only reprojecting can save you now 290 dirty = true; 291 return; 292 } 293 else if (starting) { 294 x = starting.x + event.panDelta.x; 295 y = starting.y + event.panDelta.y; 296 } 297 else { 298 // TODO: this shouldn't really ever happen, and the following might not work: 299 x = event.panDelta.x; 300 y = event.panDelta.y; 301 } 302 } 303 304 protected function onMapStopPanning(event:MapEvent):void 305 { 306 if (starting) { 307 x = starting.x; 308 y = starting.y; 309 starting = null; 310 } 311 else { 312 // make sure we're centered 313 x = map.getWidth() / 2; 314 y = map.getHeight() / 2; 315 } 316 dirty = true; 317 //updateClips(); 318 } 319 320 protected function onMapResized(event:MapEvent):void 321 { 322 x = event.newSize[0] / 2; 323 y = event.newSize[1] / 2; 324 dirty = true; 325 updateClips(); // force redraw because flash seems stingy about it 326 } 327 328 protected function onMapStartZooming(event:MapEvent):void 329 { 330 dirty = true; 331 } 332 333 protected function onMapExtentChanged(event:MapEvent):void 334 { 335 dirty = true; 336 } 337 338 protected function onMapStopZooming(event:MapEvent):void 339 { 322 var p:Point = map.grid.coordinatePoint(drawCoord); 323 this.x = p.x; 324 this.y = p.y; 325 } 326 327 protected function onMapZoomedBy(event:MapEvent):void 328 { 329 cacheAsBitmap = false; 340 330 if (scaleZoom) { 341 //trace("scaling zoom back to 1"); 342 scaleX = scaleY = 1.0; 343 } 344 dirty = true; 345 } 346 347 protected function onMapZoomedBy(event:MapEvent):void 348 { 349 if (scaleZoom) { 350 //trace("scaling zoom"); 351 scaleX = scaleY = Math.pow(2, event.zoomDelta); 331 scaleX = scaleY = Math.pow(2, map.grid.zoomLevel - drawCoord.zoom); 352 332 } 353 333 else { … … 355 335 } 356 336 } 337 338 protected function onMapStartPanning(event:MapEvent):void 339 { 340 // optimistically, we set this to true in case we're just moving 341 cacheAsBitmap = true; 342 } 343 344 protected function onMapStartZooming(event:MapEvent):void 345 { 346 // overrule onMapStartPanning if there's scaling involved 347 cacheAsBitmap = false; 348 } 349 350 protected function onMapStopPanning(event:MapEvent):void 351 { 352 // tidy up 353 cacheAsBitmap = false; 354 dirty = true; 355 } 356 357 protected function onMapStopZooming(event:MapEvent):void 358 { 359 dirty = true; 360 } 361 362 protected function onMapResized(event:MapEvent):void 363 { 364 x = map.getWidth() / 2; 365 y = map.getHeight() / 2; 366 dirty = true; 367 updateClips(); // force redraw because flash seems stingy about it 368 } 369 357 370 358 371 protected function onMapProviderChanged(event:MapEvent):void 359 372 { 360 var mapProvider:IMapProvider = event.newProvider;373 var mapProvider:IMapProvider = map.getMapProvider(); 361 374 if (mapProvider.geometry() != previousGeometry) 362 375 { … … 365 378 } 366 379 } 380 381 ///// Invalidations... 367 382 368 383 protected function set dirty(d:Boolean):void … … 379 394 } 380 395 396 ////// Marker Events... 397 381 398 /** 382 399 * Dispatches MarkerEvent.CLICK when a marker is clicked. trunk/as3/lib/com/modestmaps/core/PolygonClip.as
r670 r671 6 6 import flash.geom.Rectangle; 7 7 8 /** 9 * PolygonClip extends MarkerClip to take the bounds of the marker into account when showing/hiding, 10 * and to trigger a redraw of content that needs scaling. 11 * 12 * To trigger the redraw, markers must implement the Redrawable interface provided in this package. 13 * 14 * See PolygonMarker for an example, but if you need multi-geometries, complex styling, holes etc., 15 * you'll need to write your own for the moment. 16 * 17 */ 8 18 public class PolygonClip extends MarkerClip 9 19 { … … 11 21 { 12 22 super(map); 13 //this.scaleZoom = true;23 this.scaleZoom = true; 14 24 this.markerSortFunction = null 15 25 } … … 17 27 override protected function markerInBounds(marker:DisplayObject, w:Number, h:Number):Boolean 18 28 { 19 var rect:Rectangle = new Rectangle(-w, -h, w*2, h*2);29 var rect:Rectangle = new Rectangle(-w, -h, w*2, h*2); 20 30 return rect.intersects(marker.getBounds(this)); 21 } 31 } 32 33 override public function updateClip(marker:DisplayObject):Boolean 34 { 35 var needsSort:Boolean = super.updateClip(marker); 36 if (contains(marker) && marker is Redrawable) { 37 Redrawable(marker).redraw(); 38 } 39 return needsSort; 40 } 22 41 23 42 } trunk/as3/lib/com/modestmaps/core/PolygonMarker.as
r670 r671 2 2 { 3 3 import com.modestmaps.Map; 4 import com.modestmaps.events.MapEvent;5 4 import com.modestmaps.geo.Location; 6 5 6 import flash.display.LineScaleMode; 7 7 import flash.display.Sprite; 8 8 import flash.events.Event; 9 9 import flash.geom.Point; 10 10 11 public class PolygonMarker extends Sprite 11 public class PolygonMarker extends Sprite implements Redrawable 12 12 { 13 13 protected var map:Map; 14 14 protected var drawZoom:Number; 15 15 16 public var zoomTolerance:Number = 4; 17 16 18 public var locations:Array; 19 protected var coordinates:Array; 17 20 public var extent:MapExtent; 18 21 public var location:Location; … … 32 35 this.mouseEnabled = false; 33 36 34 map.addEventListener(MapEvent.EXTENT_CHANGED, rescale);35 map.addEventListener(MapEvent.ZOOMED_BY, rescale);36 map.addEventListener(MapEvent.STOP_ZOOMING, redraw);37 38 37 if (locations && locations.length > 0) { 39 38 this.locations = locations; 40 39 this.extent = MapExtent.fromLocations(locations); 41 40 this.location = locations[0] as Location; 41 this.coordinates = locations.map(l2c); 42 42 } 43 43 } 44 45 protected function l2c(l:Location, ...rest):Coordinate 46 { 47 return map.getMapProvider().locationCoordinate(l); 48 } 44 49 45 public function rescale(event:Event=null):void46 {47 scaleX = scaleY = Math.pow(2, map.grid.zoomLevel - drawZoom);48 }49 50 50 public function redraw(event:Event=null):void 51 { 52 drawZoom = map.grid.zoomLevel; 51 { 52 var grid:TileGrid = map.grid; 53 54 if (drawZoom && Math.abs(grid.zoomLevel-drawZoom) < zoomTolerance) { 55 scaleX = scaleY = Math.pow(2, grid.zoomLevel-drawZoom); 56 return; 57 } 58 59 drawZoom = grid.zoomLevel; 53 60 scaleX = scaleY = 1; 54 61 55 var firstPoint:Point = map.locationPoint(location)62 var firstPoint:Point = grid.coordinatePoint(coordinates[0]); // map.locationPoint(location) 56 63 graphics.clear(); 57 64 if (line && lineAlpha) { 58 graphics.lineStyle(lineThickness, lineColor, lineAlpha );65 graphics.lineStyle(lineThickness, lineColor, lineAlpha, false, LineScaleMode.NONE); 59 66 } 60 67 else { … … 65 72 } 66 73 graphics.moveTo(0, 0); 67 for each (var loc:Location in locations.slice(1)) { 68 var p:Point = map.locationPoint(loc); 74 var p:Point; 75 for each (var coord:Coordinate in coordinates.slice(1)) { 76 p = grid.coordinatePoint(coord); 69 77 graphics.lineTo(p.x-firstPoint.x, p.y-firstPoint.y); 70 78 } 71 if (loc.lat != location.lat && loc.lon != location.lon) {79 /* if (loc.lat != location.lat && loc.lon != location.lon) { 72 80 graphics.lineTo(0, 0); 73 } 81 } */ 74 82 if (fillAlpha) { 75 83 graphics.endFill(); trunk/as3/lib/com/modestmaps/core/TileGrid.as
r647 r671 165 165 166 166 // for pan events 167 protected var startPan: Point;167 protected var startPan:Coordinate; 168 168 public var panning:Boolean; 169 169 … … 339 339 var boundsEnforced:Boolean = enforceBounds(); 340 340 341 if (zooming && panning) { 342 // doesn't bubble, unlike MapEvent 343 // Map will pick this up and dispatch MapEvent.EXTENT_CHANGED for us 344 dispatchEvent(new Event(Event.CHANGE, false, false)); 345 } 346 else if (panning) { 347 if (startPan) { 348 dispatchEvent(new MapEvent(MapEvent.PANNED, new Point(worldMatrix.tx-startPan.x, worldMatrix.ty-startPan.y))); 349 } 350 else { 351 // TODO: this should probably be an error, but I'm not convinced that it can't happen yet :) 352 //trace("panning but no startPan"); 353 } 354 } 355 else if (zooming) { 356 var zoomEvent:MapEvent = new MapEvent(MapEvent.ZOOMED_BY, zoomLevel-startZoom); 357 // this might also be useful 358 zoomEvent.zoomLevel = zoomLevel; 359 dispatchEvent(zoomEvent); 341 if (zooming || panning) { 342 if (panning) { 343 var pt:Point = coordinatePoint(startPan); 344 dispatchEvent(new MapEvent(MapEvent.PANNED, pt.subtract(new Point(mapWidth/2, mapHeight/2)))); 345 } 346 if (zooming) { 347 var zoomEvent:MapEvent = new MapEvent(MapEvent.ZOOMED_BY, zoomLevel-startZoom); 348 // this might also be useful 349 zoomEvent.zoomLevel = zoomLevel; 350 dispatchEvent(zoomEvent); 351 } 360 352 } 361 353 else if (boundsEnforced) { … … 1079 1071 { 1080 1072 // this is the same as coord.zoomTo, but doesn't make a new Coordinate: 1081 var zoomFactor:Number = Math.pow(2, zoomLevel - coord.zoom) 1073 var zoomFactor:Number = Math.pow(2, zoomLevel - coord.zoom); 1074 //zoomFactor *= tileWidth/scale; 1082 1075 var zoomedColumn:Number = coord.column * zoomFactor; 1083 1076 var zoomedRow:Number = coord.row * zoomFactor; 1084 1077 1085 var tl:Coordinate = topLeftCoordinate;1078 var tl:Coordinate = topLeftCoordinate; 1086 1079 var br:Coordinate = bottomRightCoordinate; 1087 1080 … … 1089 1082 var rows:Number = br.row - tl.row; 1090 1083 1091 var screenPoint:Point = new Point(mapWidth * (zoomedColumn-tl.column) / cols, mapHeight * (zoomedRow-tl.row) / rows); 1084 var screenPoint:Point = new Point(mapWidth * (zoomedColumn-tl.column) / cols, mapHeight * (zoomedRow-tl.row) / rows); 1085 1086 //var screenPoint:Point = worldMatrix.transformPoint(new Point(zoomedColumn, zoomedRow)); 1092 1087 1093 1088 if (context && context != this) … … 1121 1116 } 1122 1117 } 1123 startPan = new Point(tx, ty);1118 startPan = centerCoordinate.copy(); 1124 1119 panning = true; 1125 1120 dispatchEvent(new MapEvent(MapEvent.START_PANNING));
