Upload
360conferences
View
841
Download
0
Tags:
Embed Size (px)
DESCRIPTION
In this session we will demonstrate the Flex Mapping API For ArcGIS Server, where we will deconstruct live real-world mapping applications and algorithms such as dense clustering, auto labeling of features, collaborative editing, real-time asset tracking and client/server collaborative Geo-Processing. In addition, we will demonstrate how to create your own layer, geometry and symbol extensions for superior rendering performance taking advantage of the FP10 drawing API.
Citation preview
Yet AnotherMapping API - Not !
Mansour [email protected]
ArcGIS Services
• Map Tiles ESRI / Virtual Earth (token)
• Geocoding / Reverse
• Query / Identify
• Routing with Barriers and Time Windows
• Buffer / Projection
• GeoProcessing
You & ArcGIS
BlazePHP.Net
Local AGS
Map “Hello World”
1.<?xml version="1.0" encoding="utf-8"?>2.<mx:Application3. xmlns:mx="http://www.adobe.com/2006/mxml"4. xmlns:esri="http://www.esri.com/2008/ags"5. layout="absolute"6. >7. <esri:Map id="map">8. <esri:ArcGISTiledMapServiceLayer url=”http://host/rest/map”/> 9. </esri:Map> 10.</mx:Application>
Map “Hello World”
1.<?xml version="1.0" encoding="utf-8"?>2.<mx:Application3. xmlns:mx="http://www.adobe.com/2006/mxml"4. xmlns:esri="http://www.esri.com/2008/ags"5. layout="absolute"6. >7. <esri:Map id="map">8. <esri:ArcGISTiledMapServiceLayer url=”http://host/rest/map”/> 9. </esri:Map> 10.</mx:Application>
Map “Hello World”
1.<?xml version="1.0" encoding="utf-8"?>2.<mx:Application3. xmlns:mx="http://www.adobe.com/2006/mxml"4. xmlns:esri="http://www.esri.com/2008/ags"5. layout="absolute"6. >7. <esri:Map id="map" openHandCursorVisible="false" zoomSliderVisible="false">8. <esri:ArcGISTiledMapServiceLayer id="layer" url="{cb.selectedItem.url}"/> 9. </esri:Map>10. <mx:ComboBox id="cb" dataProvider="{[11. {label:'Imagery',url:'http://host/rest/Image'},12. {label:'Physical',url:'http://host/rest/Physical'}13. ]}"/> 14.</mx:Application>
1.<?xml version="1.0" encoding="utf-8"?>2.<mx:Application3. xmlns:mx="http://www.adobe.com/2006/mxml"4. xmlns:esri="http://www.esri.com/2008/ags"5. layout="absolute"6. >7. <esri:Map id="map" openHandCursorVisible="false" zoomSliderVisible="false">8. <esri:ArcGISTiledMapServiceLayer id="layer" url="{cb.selectedItem.url}"/> 9. </esri:Map>10. <mx:ComboBox id="cb" dataProvider="{[11. {label:'Imagery',url:'http://host/rest/Image'},12. {label:'Physical',url:'http://host/rest/Physical'}13. ]}"/> 14.</mx:Application>
1.<?xml version="1.0" encoding="utf-8"?>2.<mx:Application3. xmlns:mx="http://www.adobe.com/2006/mxml"4. xmlns:esri="http://www.esri.com/2008/ags"5. layout="absolute"6. >7. <esri:Map id="map" openHandCursorVisible="false" zoomSliderVisible="false">8. <esri:ArcGISTiledMapServiceLayer id="layer" url="{cb.selectedItem.url}"/> 9. </esri:Map>10. <mx:ComboBox id="cb" dataProvider="{[11. {label:'Imagery',url:'http://host/rest/Image'},12. {label:'Physical',url:'http://host/rest/Physical'}13. ]}"/> 14.</mx:Application>
GeoProcessingDriveTimes
1. <esri:Geoprocessor id="gp" url="<GeoProcessesorURL>" showBusyCursor="true"/>2. <esri:Map id="map" openHandCursorVisible="false" mapClick="mapClickHandler(event)">3. <esri:extent>4. <esri:Extent xmin="-95.41" ymin="38.86" xmax="-95.1" ymax="39.06">5. <esri:SpatialReference wkid="4326"/>6. </esri:Extent>7. </esri:extent>8. <esri:ArcGISTiledMapServiceLayer url="<MapServiceURL>"/>9. <esri:GraphicsLayer id="polygonLayer" graphicProvider="{gp.executeFirstFeatureSet.features}">10. <esri:renderer>11. <esri:UniqueValueRenderer attribute="ToBreak">12. <esri:UniqueValueInfo value="1">13. <esri:symbol>14. <esri:SimpleFillSymbol alpha="0.5" color="0xFF0000"/>15. </esri:symbol>16. </esri:UniqueValueInfo>17. <esri:UniqueValueInfo value="2">18. <esri:symbol>19. <esri:SimpleFillSymbol alpha="0.5" color="0x00FF00"/>20. </esri:symbol>21. </esri:UniqueValueInfo>22. <esri:UniqueValueInfo value="3">23. <esri:symbol>24. <esri:SimpleFillSymbol alpha="0.5" color="0x0000FF"/>25. </esri:symbol>26. </esri:UniqueValueInfo>27. </esri:UniqueValueRenderer>28. </esri:renderer>29. </esri:GraphicsLayer>30. <esri:GraphicsLayer id="pointLayer"/>31. </esri:Map>
1. <esri:Geoprocessor id="gp" url="<GeoProcessesorURL>" showBusyCursor="true"/>2. <esri:Map id="map" openHandCursorVisible="false" mapClick="mapClickHandler(event)">3. <esri:extent>4. <esri:Extent xmin="-95.41" ymin="38.86" xmax="-95.1" ymax="39.06">5. <esri:SpatialReference wkid="4326"/>6. </esri:Extent>7. </esri:extent>8. <esri:ArcGISTiledMapServiceLayer url="<MapServiceURL>"/>9. <esri:GraphicsLayer id="polygonLayer" graphicProvider="{gp.executeFirstFeatureSet.features}">10. <esri:renderer>11. <esri:UniqueValueRenderer attribute="ToBreak">12. <esri:UniqueValueInfo value="1">13. <esri:symbol>14. <esri:SimpleFillSymbol alpha="0.5" color="0xFF0000"/>15. </esri:symbol>16. </esri:UniqueValueInfo>17. <esri:UniqueValueInfo value="2">18. <esri:symbol>19. <esri:SimpleFillSymbol alpha="0.5" color="0x00FF00"/>20. </esri:symbol>21. </esri:UniqueValueInfo>22. <esri:UniqueValueInfo value="3">23. <esri:symbol>24. <esri:SimpleFillSymbol alpha="0.5" color="0x0000FF"/>25. </esri:symbol>26. </esri:UniqueValueInfo>27. </esri:UniqueValueRenderer>28. </esri:renderer>29. </esri:GraphicsLayer>30. <esri:GraphicsLayer id="pointLayer"/>31. </esri:Map>
1. <esri:Geoprocessor id="gp" url="<GeoProcessesorURL>" showBusyCursor="true"/>2. <esri:Map id="map" openHandCursorVisible="false" mapClick="mapClickHandler(event)">3. <esri:extent>4. <esri:Extent xmin="-95.41" ymin="38.86" xmax="-95.1" ymax="39.06">5. <esri:SpatialReference wkid="4326"/>6. </esri:Extent>7. </esri:extent>8. <esri:ArcGISTiledMapServiceLayer url="<MapServiceURL>"/>9. <esri:GraphicsLayer id="polygonLayer" graphicProvider="{gp.executeFirstFeatureSet.features}">10. <esri:renderer>11. <esri:UniqueValueRenderer attribute="ToBreak">12. <esri:UniqueValueInfo value="1">13. <esri:symbol>14. <esri:SimpleFillSymbol alpha="0.5" color="0xFF0000"/>15. </esri:symbol>16. </esri:UniqueValueInfo>17. <esri:UniqueValueInfo value="2">18. <esri:symbol>19. <esri:SimpleFillSymbol alpha="0.5" color="0x00FF00"/>20. </esri:symbol>21. </esri:UniqueValueInfo>22. <esri:UniqueValueInfo value="3">23. <esri:symbol>24. <esri:SimpleFillSymbol alpha="0.5" color="0x0000FF"/>25. </esri:symbol>26. </esri:UniqueValueInfo>27. </esri:UniqueValueRenderer>28. </esri:renderer>29. </esri:GraphicsLayer>30. <esri:GraphicsLayer id="pointLayer"/>31. </esri:Map>
1. <esri:Geoprocessor id="gp" url="<GeoProcessesorURL>" showBusyCursor="true"/>2. <esri:Map id="map" openHandCursorVisible="false" mapClick="mapClickHandler(event)">3. <esri:extent>4. <esri:Extent xmin="-95.41" ymin="38.86" xmax="-95.1" ymax="39.06">5. <esri:SpatialReference wkid="4326"/>6. </esri:Extent>7. </esri:extent>8. <esri:ArcGISTiledMapServiceLayer url="<MapServiceURL>"/>9. <esri:GraphicsLayer id="polygonLayer" graphicProvider="{gp.executeFirstFeatureSet.features}">10. <esri:renderer>11. <esri:UniqueValueRenderer attribute="ToBreak">12. <esri:UniqueValueInfo value="1">13. <esri:symbol>14. <esri:SimpleFillSymbol alpha="0.5" color="0xFF0000"/>15. </esri:symbol>16. </esri:UniqueValueInfo>17. <esri:UniqueValueInfo value="2">18. <esri:symbol>19. <esri:SimpleFillSymbol alpha="0.5" color="0x00FF00"/>20. </esri:symbol>21. </esri:UniqueValueInfo>22. <esri:UniqueValueInfo value="3">23. <esri:symbol>24. <esri:SimpleFillSymbol alpha="0.5" color="0x0000FF"/>25. </esri:symbol>26. </esri:UniqueValueInfo>27. </esri:UniqueValueRenderer>28. </esri:renderer>29. </esri:GraphicsLayer>30. <esri:GraphicsLayer id="pointLayer"/>31. </esri:Map>
1.<mx:Script>2. <![CDATA[3. import com.esri.ags.tasks.FeatureSet;4. import com.esri.ags.Graphic;5. import com.esri.ags.events.MapMouseEvent;
7. private function mapClickHandler(event:MapMouseEvent):void8. {9. const graphic:Graphic = new Graphic(event.mapPoint);10. pointLayer.clear();11. pointLayer.add(graphic);12. const featureSet:FeatureSet = new FeatureSet([graphic]);13. gp.execute({"Input_Location": featureSet, "Drive_Times": "1 2 3"});14. }15. ]]>16.</mx:Script>
1.<mx:Script>2. <![CDATA[3. import com.esri.ags.tasks.FeatureSet;4. import com.esri.ags.Graphic;5. import com.esri.ags.events.MapMouseEvent;
7. private function mapClickHandler(event:MapMouseEvent):void8. {9. const graphic:Graphic = new Graphic(event.mapPoint);10. pointLayer.clear();11. pointLayer.add(graphic);12. const featureSet:FeatureSet = new FeatureSet([graphic]);13. gp.execute({"Input_Location": featureSet, "Drive_Times": "1 2 3"});14. }15. ]]>16.</mx:Script>
DemoSample 1-2DriveTimes
Many Children Layers
Many Graphic Layers
GraphicLayer
GraphicLayer
• graphicProvider
• ArrayCollection
• renderer
• graphic with no symbol
Graphic
Graphic
• UIComponent
• Flex life cycle management
• geometry
• symbol
• attributes
Graphic/Geometry
Graphic/Geometry
• Geometry - base class
• MapPoint
• Polyline
• Polygon
Polyline/Polygon
Polyline/Polygon
• Multi Part Geometry
• Islands of Hawaii
Graphic/Symbol
Graphic/Symbol
• Symbol - base class
• Draws geometry of Graphic
• Uses Flash Drawing API
Graphic/Attributes
Graphic/Attributes
• Any Object !
• Attach any dynamic property to Graphic
Geometry/Symbol
Geometry/Symbol
• [Bindable] Properties
• Dispatch CHANGE event
DemoSample 3-7
LCDS
LCDS
• Remote Objects
• Messaging
• Data Services
Feature
Feature
• Serializable server side object
• Properties
• featureID:int;
• geometry:IGeometry;
• attributes:ASObject;
public class Feature implements Serializable{ private int m_featureId; private IGeometry m_geometry; private ASObject m_attributes;
public Feature() { }
public int getFeatureId() { return m_featureId; }
public void setFeatureId(final int featureId) { m_featureId = featureId; }
...
public class MapPoint implements IGeometry{ private double m_x; private double m_y; private SpatialReference m_spatialReference;
public MapPoint(){ }
public MapPoint(final double x, final double y){ m_x = x; m_y = y; }
public double getX(){ return m_x; }
public void setX(final double x){ m_x = x; }
...
DS Assembler
• fill
• createItem
• getItem
• updateItem
• deleteItem
private int m_featureId = 1;private Map<Integer, Feature> m_map = new ConcurrentHashMap<Integer, Feature>(17);
public Collection fill(final List fillParameters){ return m_map.values();}
public Object getItem(final Map map){ return m_map.get(map.get("featureId"));}
public void createItem(final Object newVersion){ final Feature Feature = (Feature) newVersion; Feature.setFeatureId(m_featureId++); m_map.put(Feature.getFeatureId(), Feature);}
public void updateItem(final Object newVersion, final Object prevVersion, final List changes){ final Feature Feature = (Feature) newVersion; m_map.put(Feature.getFeatureId(), Feature);}
public void deleteItem(final Object prevVersion){ final Feature Feature = (Feature) prevVersion; m_map.remove(Feature.getFeatureId());}
private int m_featureId = 1;private Map<Integer, Feature> m_map = new ConcurrentHashMap<Integer, Feature>(17);
public Collection fill(final List fillParameters){ return m_map.values();}
public Object getItem(final Map map){ return m_map.get(map.get("featureId"));}
public void createItem(final Object newVersion){ final Feature Feature = (Feature) newVersion; Feature.setFeatureId(m_featureId++); m_map.put(Feature.getFeatureId(), Feature);}
public void updateItem(final Object newVersion, final Object prevVersion, final List changes){ final Feature Feature = (Feature) newVersion; m_map.put(Feature.getFeatureId(), Feature);}
public void deleteItem(final Object prevVersion){ final Feature Feature = (Feature) prevVersion; m_map.remove(Feature.getFeatureId());}
private int m_featureId = 1;private Map<Integer, Feature> m_map = new ConcurrentHashMap<Integer, Feature>(17);
public Collection fill(final List fillParameters){ return m_map.values();}
public Object getItem(final Map map){ return m_map.get(map.get("featureId"));}
public void createItem(final Object newVersion){ final Feature Feature = (Feature) newVersion; Feature.setFeatureId(m_featureId++); m_map.put(Feature.getFeatureId(), Feature);}
public void updateItem(final Object newVersion, final Object prevVersion, final List changes){ final Feature Feature = (Feature) newVersion; m_map.put(Feature.getFeatureId(), Feature);}
public void deleteItem(final Object prevVersion){ final Feature Feature = (Feature) prevVersion; m_map.remove(Feature.getFeatureId());}
private int m_featureId = 1;private Map<Integer, Feature> m_map = new ConcurrentHashMap<Integer, Feature>(17);
public Collection fill(final List fillParameters){ return m_map.values();}
public Object getItem(final Map map){ return m_map.get(map.get("featureId"));}
public void createItem(final Object newVersion){ final Feature Feature = (Feature) newVersion; Feature.setFeatureId(m_featureId++); m_map.put(Feature.getFeatureId(), Feature);}
public void updateItem(final Object newVersion, final Object prevVersion, final List changes){ final Feature Feature = (Feature) newVersion; m_map.put(Feature.getFeatureId(), Feature);}
public void deleteItem(final Object prevVersion){ final Feature Feature = (Feature) prevVersion; m_map.remove(Feature.getFeatureId());}
private int m_featureId = 1;private Map<Integer, Feature> m_map = new ConcurrentHashMap<Integer, Feature>(17);
public Collection fill(final List fillParameters){ return m_map.values();}
public Object getItem(final Map map){ return m_map.get(map.get("featureId"));}
public void createItem(final Object newVersion){ final Feature Feature = (Feature) newVersion; Feature.setFeatureId(m_featureId++); m_map.put(Feature.getFeatureId(), Feature);}
public void updateItem(final Object newVersion, final Object prevVersion, final List changes){ final Feature Feature = (Feature) newVersion; m_map.put(Feature.getFeatureId(), Feature);}
public void deleteItem(final Object prevVersion){ final Feature Feature = (Feature) prevVersion; m_map.remove(Feature.getFeatureId());}
private int m_featureId = 1;private Map<Integer, Feature> m_map = new ConcurrentHashMap<Integer, Feature>(17);
public Collection fill(final List fillParameters){ return m_map.values();}
public Object getItem(final Map map){ return m_map.get(map.get("featureId"));}
public void createItem(final Object newVersion){ final Feature Feature = (Feature) newVersion; Feature.setFeatureId(m_featureId++); m_map.put(Feature.getFeatureId(), Feature);}
public void updateItem(final Object newVersion, final Object prevVersion, final List changes){ final Feature Feature = (Feature) newVersion; m_map.put(Feature.getFeatureId(), Feature);}
public void deleteItem(final Object prevVersion){ final Feature Feature = (Feature) prevVersion; m_map.remove(Feature.getFeatureId());}
data-management-config.xml
data-management-config.xml<destination id="feature"> <properties> <factory>spring</factory> <source>featureAssembler</source> <scope>application</scope> <use-transactions>false</use-transactions> <metadata> <identity property="featureId"/> </metadata> <network> <paging enabled="false" pageSize="10"/> </network> </properties></destination>
Back To The Client :-)
package com.esri.cats{ import com.esri.ags.SpatialReference; import com.esri.ags.geometry.MapPoint; import flash.net.registerClassAlias; import mx.core.IMXMLObject;
public class ClassAliasRegistry implements IMXMLObject { public function initialized(document:Object, id:String):void { registerClassAlias("com.esri.cats.MapPoint", MapPoint); registerClassAlias("com.esri.cats.SpatialReference", SpatialReference); } }}
package com.esri.cats{ import com.esri.ags.SpatialReference; import com.esri.ags.geometry.MapPoint; import flash.net.registerClassAlias; import mx.core.IMXMLObject;
public class ClassAliasRegistry implements IMXMLObject { public function initialized(document:Object, id:String):void { registerClassAlias("com.esri.cats.MapPoint", MapPoint); registerClassAlias("com.esri.cats.SpatialReference", SpatialReference); } }}
1.package com.esri.cats2.{3. import com.esri.ags.geometry.Geometry;
5. [Managed]6. [RemoteClass(alias="com.esri.cats.Feature")]7. public class Feature8. {9. public var featureId:int;10. public var geometry:Geometry;11. public var attributes:Object;12. 13. public function Feature()14. {15. }16. 17. } 18.}
1.package com.esri.cats2.{3. import com.esri.ags.geometry.Geometry;
5. [Managed]6. [RemoteClass(alias="com.esri.cats.Feature")]7. public class Feature8. {9. public var featureId:int;10. public var geometry:Geometry;11. public var attributes:Object;12. 13. public function Feature()14. {15. }16. 17. } 18.}
1.<cats:ClassAliasRegistry/>2.<mx:ArrayCollection id="features"3. collectionChange="collectionChangeHandler(event)"/>4.<mx:DataService id="ds" destination="feature"/>5.<esri:Map id="map" load="ds.fill(features)">6. <esri:GraphicsLayer id="graphicsLayer"/>7. <esri:GraphicsLayer id="pointLayer">8. <esri:symbol>9. <esri:SimpleMarkerSymbol color="0xFFFF00"/>10. </esri:symbol>11. </esri:GraphicsLayer>12.</esri:Map>
1.<cats:ClassAliasRegistry/>2.<mx:ArrayCollection id="features"3. collectionChange="collectionChangeHandler(event)"/>4.<mx:DataService id="ds" destination="feature"/>5.<esri:Map id="map" load="ds.fill(features)">6. <esri:GraphicsLayer id="graphicsLayer"/>7. <esri:GraphicsLayer id="pointLayer">8. <esri:symbol>9. <esri:SimpleMarkerSymbol color="0xFFFF00"/>10. </esri:symbol>11. </esri:GraphicsLayer>12.</esri:Map>
1.<cats:ClassAliasRegistry/>2.<mx:ArrayCollection id="features"3. collectionChange="collectionChangeHandler(event)"/>4.<mx:DataService id="ds" destination="feature"/>5.<esri:Map id="map" load="ds.fill(features)">6. <esri:GraphicsLayer id="graphicsLayer"/>7. <esri:GraphicsLayer id="pointLayer">8. <esri:symbol>9. <esri:SimpleMarkerSymbol color="0xFFFF00"/>10. </esri:symbol>11. </esri:GraphicsLayer>12.</esri:Map>
1.<cats:ClassAliasRegistry/>2.<mx:ArrayCollection id="features"3. collectionChange="collectionChangeHandler(event)"/>4.<mx:DataService id="ds" destination="feature"/>5.<esri:Map id="map" load="ds.fill(features)">6. <esri:GraphicsLayer id="graphicsLayer"/>7. <esri:GraphicsLayer id="pointLayer">8. <esri:symbol>9. <esri:SimpleMarkerSymbol color="0xFFFF00"/>10. </esri:symbol>11. </esri:GraphicsLayer>12.</esri:Map>
1.<cats:ClassAliasRegistry/>2.<mx:ArrayCollection id="features"3. collectionChange="collectionChangeHandler(event)"/>4.<mx:DataService id="ds" destination="feature"/>5.<esri:Map id="map" load="ds.fill(features)">6. <esri:GraphicsLayer id="graphicsLayer"/>7. <esri:GraphicsLayer id="pointLayer">8. <esri:symbol>9. <esri:SimpleMarkerSymbol color="0xFFFF00"/>10. </esri:symbol>11. </esri:GraphicsLayer>12.</esri:Map>
private function collectionChangeHandler(event:CollectionEvent):void{ switch (event.kind) { case CollectionEventKind.RESET: doReset(event); break; case CollectionEventKind.UPDATE: doUpdate(event); break; }}
private function doReset(event:CollectionEvent):void{ graphicsLayer.clear(); m_graphicsDict = new Dictionary(); for each (var feature:Feature in features) { var graphic:Graphic = new Graphic(feature.geometry, null, feature); graphic.buttonMode = true; graphic.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler); graphic.toolTip = String(feature.attributes.coords).replace(" ", "\n"); graphicsLayer.add(graphic); m_graphicsDict[feature.featureId] = graphic; }}
private function doReset(event:CollectionEvent):void{ graphicsLayer.clear(); m_graphicsDict = new Dictionary(); for each (var feature:Feature in features) { var graphic:Graphic = new Graphic(feature.geometry, null, feature); graphic.buttonMode = true; graphic.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler); graphic.toolTip = String(feature.attributes.coords).replace(" ", "\n"); graphicsLayer.add(graphic); m_graphicsDict[feature.featureId] = graphic; }}
private function doReset(event:CollectionEvent):void{ graphicsLayer.clear(); m_graphicsDict = new Dictionary(); for each (var feature:Feature in features) { var graphic:Graphic = new Graphic(feature.geometry, null, feature); graphic.buttonMode = true; graphic.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler); graphic.toolTip = String(feature.attributes.coords).replace(" ", "\n"); graphicsLayer.add(graphic); m_graphicsDict[feature.featureId] = graphic; }}
private function doUpdate(event:CollectionEvent):void{ for each (var propertyChangeEvent:PropertyChangeEvent in event.items) { var feature:Feature = propertyChangeEvent.target as Feature; if (propertyChangeEvent.property === "geometry") { var graphic:Graphic = m_graphicsDict[feature.featureId]; if (graphic) { graphic.geometry = feature.geometry; } } }}
private function doUpdate(event:CollectionEvent):void{ for each (var propertyChangeEvent:PropertyChangeEvent in event.items) { var feature:Feature = propertyChangeEvent.target as Feature; if (propertyChangeEvent.property === "geometry") { var graphic:Graphic = m_graphicsDict[feature.featureId]; if (graphic) { graphic.geometry = feature.geometry; } } }}
private function doUpdate(event:CollectionEvent):void{ for each (var propertyChangeEvent:PropertyChangeEvent in event.items) { var feature:Feature = propertyChangeEvent.target as Feature; if (propertyChangeEvent.property === "geometry") { var graphic:Graphic = m_graphicsDict[feature.featureId]; if (graphic) { graphic.geometry = feature.geometry; } } }}
1.private function mouseDownHandler(event:MouseEvent):void2.{3. const graphic:Graphic = event.target as Graphic;4. if (graphic)5. {6. m_feature = graphic.attributes as Feature;7. m_graphic.geometry = map.toMapFromStage(event.stageX, event.stageY);8. pointLayer.add(m_graphic);9. map.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);10. map.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);11. }12.}
14.private function mouseMoveHandler(event:MouseEvent):void15.{16. m_graphic.geometry = map.toMapFromStage(event.stageX, event.stageY);17. event.updateAfterEvent();18.}
20.private function mouseUpHandler(event:MouseEvent):void21.{22. m_feature.geometry = m_graphic.geometry; // ALL DS FM is Here :-)23. m_feature = null;24. pointLayer.clear();25. map.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);26. map.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);27.}
1.private function mouseDownHandler(event:MouseEvent):void2.{3. const graphic:Graphic = event.target as Graphic;4. if (graphic)5. {6. m_feature = graphic.attributes as Feature;7. m_graphic.geometry = map.toMapFromStage(event.stageX, event.stageY);8. pointLayer.add(m_graphic);9. map.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);10. map.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);11. }12.}
14.private function mouseMoveHandler(event:MouseEvent):void15.{16. m_graphic.geometry = map.toMapFromStage(event.stageX, event.stageY);17. event.updateAfterEvent();18.}
20.private function mouseUpHandler(event:MouseEvent):void21.{22. m_feature.geometry = m_graphic.geometry; // ALL DS FM is Here :-)23. m_feature = null;24. pointLayer.clear();25. map.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);26. map.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);27.}
1.private function mouseDownHandler(event:MouseEvent):void2.{3. const graphic:Graphic = event.target as Graphic;4. if (graphic)5. {6. m_feature = graphic.attributes as Feature;7. m_graphic.geometry = map.toMapFromStage(event.stageX, event.stageY);8. pointLayer.add(m_graphic);9. map.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);10. map.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);11. }12.}
14.private function mouseMoveHandler(event:MouseEvent):void15.{16. m_graphic.geometry = map.toMapFromStage(event.stageX, event.stageY);17. event.updateAfterEvent();18.}
20.private function mouseUpHandler(event:MouseEvent):void21.{22. m_feature.geometry = m_graphic.geometry; // ALL DS FM is Here :-)23. m_feature = null;24. pointLayer.clear();25. map.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);26. map.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);27.}
Demo CATS
“Lots” Features
Spatial Index
Spatial Index
• RTree
• QuadTree
• Grid / Trellis
• Simple
• Efficient (points)
• Good enough !
0,0
width,height
0,0
width,height
Xmin,Ymin
Xmax,Ymax
0,0
width,height
Xmin,Ymin
Xmax,Ymax
0,0
width,height
Xmin,Ymin
Xmax,Ymax
0 1 2 3
0
1
2
3
Cx
Cy
0 1 2 3
0
1
2
3
(0,0)
(1,3)
(3,2)
(3,2)
Cx
Cy
Cx & Cy > 0 int
Cx & Cy < 216
Dict[(cx<<16)|cy]
Cluster : Geometry
Cluster : Geometry
• Original X
• Original Y
• Cluster X
• Cluster Y
• count
ClusterSymbol : Symbol
ClusterSymbol : Symbol
• Draws a Cluster geometry instance
• Flash drawing API
• beginFill - based on cluster count
• drawRoundedRect - based on Cx,Cy
DemoDrawSymbol Code
Adaptive Clustering
Adaptive Clustering
• JIT
• “Smart” algorithm - all client side.
• React to map extent change
Given set of map points
Given set of map pointsAssign map point to cluster set
Given set of map pointsAssign map point to cluster setdo
Given set of map pointsAssign map point to cluster setdo spatial index clusters
Given set of map pointsAssign map point to cluster setdo spatial index clusters for each cluster Ci
Given set of map pointsAssign map point to cluster setdo spatial index clusters for each cluster Ci
find adjacent clusters Cj
Given set of map pointsAssign map point to cluster setdo spatial index clusters for each cluster Ci
find adjacent clusters Cj
if Cj is close enough to Ci
Given set of map pointsAssign map point to cluster setdo spatial index clusters for each cluster Ci
find adjacent clusters Cj
if Cj is close enough to Ci
assign Cj map points to Ci
Given set of map pointsAssign map point to cluster setdo spatial index clusters for each cluster Ci
find adjacent clusters Cj
if Cj is close enough to Ci
assign Cj map points to Ci
remove Cj from cluster set
Given set of map pointsAssign map point to cluster setdo spatial index clusters for each cluster Ci
find adjacent clusters Cj
if Cj is close enough to Ci
assign Cj map points to Ci
remove Cj from cluster set adjust Ci location
Given set of map pointsAssign map point to cluster setdo spatial index clusters for each cluster Ci
find adjacent clusters Cj
if Cj is close enough to Ci
assign Cj map points to Ci
remove Cj from cluster set adjust Ci locationrepeat while overlapping clusters exist
Adjusting Ci location
Adjusting Ci location
Ci
Wi
Adjusting Ci location
Ci
Wi
Cj
Wj
Adjusting Ci location
Ci
Wi
Cj
Wj
Adjusting Ci location
Wi+Wj
Ci=(Ci Wi+CjWj)/WiWj
DemoClusterApp
HeatMaps are Bitmaps !
1.<?xml version="1.0" encoding="utf-8"?>2.<view:PrepApplication3. xmlns:mx="http://www.adobe.com/2006/mxml"4. xmlns:esri="http://www.esri.com/2008/ags"5. xmlns:controller="com.esri.controller.*"6. xmlns:view="com.esri.view.*"7. layout="vertical"8. paddingLeft="0"9. paddingRight="0"10. paddingTop="0"11. paddingBottom="0"12. >13. <controller:LoadCommand/>14. <view:PrepSlider/>15. <view:PrepMap>16. <view:extent>17. <esri:Extent xmin="-143.141073" ymin="14.930875" xmax="-48.0570833" ymax="57.649769"/>18. </view:extent>19. <esri:ArcGISTiledMapServiceLayer20. url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_Imagery_World_2D/MapServer"/>21. <view:PrepLayer/> 22. </view:PrepMap>23.</view:PrepApplication>
1.<?xml version="1.0" encoding="utf-8"?>2.<view:PrepApplication3. xmlns:mx="http://www.adobe.com/2006/mxml"4. xmlns:esri="http://www.esri.com/2008/ags"5. xmlns:controller="com.esri.controller.*"6. xmlns:view="com.esri.view.*"7. layout="vertical"8. paddingLeft="0"9. paddingRight="0"10. paddingTop="0"11. paddingBottom="0"12. >13. <controller:LoadCommand/>14. <view:PrepSlider/>15. <view:PrepMap>16. <view:extent>17. <esri:Extent xmin="-143.141073" ymin="14.930875" xmax="-48.0570833" ymax="57.649769"/>18. </view:extent>19. <esri:ArcGISTiledMapServiceLayer20. url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_Imagery_World_2D/MapServer"/>21. <view:PrepLayer/> 22. </view:PrepMap>23.</view:PrepApplication>
PrepLayer : Layer
PrepLayer : Layer
• Subclass Layer
• Override updateLayer
• Invoked by updateDisplayList
• create bitmap - lock/unlock
• bitmap.fillRect each heat map point
• graphic.bitmapFill / drawRect
PrepLayer
PrepLayer
• Kept data in 2 arrays
• x = []
• y = []
• Easy to AMF
• toScreenX/Y built-in functions
DemoPrecipitationApp
Street Tracing
Street Tracing
• A*
• Create nodes and edges
• Define barriers
• Reverse geocoding
• Custom layer - faster rendering
A* / Path Finding
Streets
Streets
“Street” Graph
“Street” Graph
• Intersection - nodes
• Street Segment - edge
• Travel distance or time - cost
Nodes/Edges/Barriers
Nodes/Edges/Barriers
A
B
C
D
E
Nodes/Edges/Barriers
A
B
C
D
E
Nodes/Edges/Barriers
A
B
C
D
E
Street Info
Main St
Street Info
Main St
100
200
Street Info
Main St
100101
200199
ReverseGeocoding
ReverseGeocoding
Main StLeft 100-200Right 101-199
ReverseGeocoding
t
Main StLeft 100-200Right 101-199
ReverseGeocoding
t
Main StLeft 100-200Right 101-199
ReverseGeocoding
dt
Main StLeft 100-200Right 101-199
ReverseGeocoding
dt
Main StLeft 100-200Right 101-199
153 Main St
Distance Calculations
Distance Calculations
A
B
C
Distance Calculations
A
B
C
P
Distance Calculations
A
B
C
Pr
r=AC AB•
∣AB∣2
Distance Calculations
A
B
C
Pr
r=AC AB•
∣AB∣2
r≺0 beyond A ↤
Distance Calculations
A
B
C
Pr
r=AC AB•
∣AB∣2
r≺0 beyond A ↤r≻0 beyond B ↦
Distance Calculations
Ax Bx Cx
Ay By Cy
12
A=
A
B
C
Pr
r=AC AB•
∣AB∣2
r≺0 beyond A ↤r≻0 beyond B ↦
Distance Calculations
Ax Bx Cx
Ay By Cy
12
A=
A
B
C
height
Pr
r=AC AB•
∣AB∣2
r≺0 beyond A ↤r≻0 beyond B ↦
Distance Calculations
Ax Bx Cx
Ay By Cy
12
A=
A
B
C
base
height
Pr
r=AC AB•
∣AB∣2
r≺0 beyond A ↤r≻0 beyond B ↦
Distance Calculations
A=base×height
2
Ax Bx Cx
Ay By Cy
12
A=
A
B
C
base
height
Pr
r=AC AB•
∣AB∣2
r≺0 beyond A ↤r≻0 beyond B ↦
Distance Calculations
A=base×height
2
Ax Bx Cx
Ay By Cy
12
A=
A
B
C
base
height
Pr
r=AC AB•
∣AB∣2
r≺0 beyond A ↤r≻0 beyond B ↦
AP=rAB
1.override protected function updateLayer():void{2. const model:Model = Model.instance;3. graphics.clear();4. graphics.lineStyle(1, 0);5. model.streetGrid.search(map.extent, streetHandler);6.}
8.private function streetHandler(street:Street, data:Object = null):void{9. for each(var path:Array in street.shpPolyline.paths){10. var index:int = 0;11. var lastX:Number = toScreenX(path[index++]);12. var lastY:Number = toScreenY(path[index++]);13. graphics.moveTo(lastX, lastY);14. while(index < path.length){15. var currX:Number = toScreenX(path[index++]);16. var currY:Number = toScreenY(path[index++]);17. if( currX !== lastX || currY !== lastY){18. graphics.lineTo(currX, currY);19. lastX = currX;20. lastY = currY; 21. }22. }23. }24.}
1.override protected function updateLayer():void{2. const model:Model = Model.instance;3. graphics.clear();4. graphics.lineStyle(1, 0);5. model.streetGrid.search(map.extent, streetHandler);6.}
8.private function streetHandler(street:Street, data:Object = null):void{9. for each(var path:Array in street.shpPolyline.paths){10. var index:int = 0;11. var lastX:Number = toScreenX(path[index++]);12. var lastY:Number = toScreenY(path[index++]);13. graphics.moveTo(lastX, lastY);14. while(index < path.length){15. var currX:Number = toScreenX(path[index++]);16. var currY:Number = toScreenY(path[index++]);17. if( currX !== lastX || currY !== lastY){18. graphics.lineTo(currX, currY);19. lastX = currX;20. lastY = currY; 21. }22. }23. }24.}
1.override protected function updateLayer():void{2. const model:Model = Model.instance;3. graphics.clear();4. graphics.lineStyle(1, 0);5. model.streetGrid.search(map.extent, streetHandler);6.}
8.private function streetHandler(street:Street, data:Object = null):void{9. for each(var path:Array in street.shpPolyline.paths){10. var index:int = 0;11. var lastX:Number = toScreenX(path[index++]);12. var lastY:Number = toScreenY(path[index++]);13. graphics.moveTo(lastX, lastY);14. while(index < path.length){15. var currX:Number = toScreenX(path[index++]);16. var currY:Number = toScreenY(path[index++]);17. if( currX !== lastX || currY !== lastY){18. graphics.lineTo(currX, currY);19. lastX = currX;20. lastY = currY; 21. }22. }23. }24.}
1.override protected function updateLayer():void{2. const model:Model = Model.instance;3. graphics.clear();4. graphics.lineStyle(1, 0);5. model.streetGrid.search(map.extent, streetHandler);6.}
8.private function streetHandler(street:Street, data:Object = null):void{9. for each(var path:Array in street.shpPolyline.paths){10. var index:int = 0;11. var lastX:Number = toScreenX(path[index++]);12. var lastY:Number = toScreenY(path[index++]);13. graphics.moveTo(lastX, lastY);14. while(index < path.length){15. var currX:Number = toScreenX(path[index++]);16. var currY:Number = toScreenY(path[index++]);17. if( currX !== lastX || currY !== lastY){18. graphics.lineTo(currX, currY);19. lastX = currX;20. lastY = currY; 21. }22. }23. }24.}
1.override protected function updateLayer():void{2. const model:Model = Model.instance;3. graphics.clear();4. graphics.lineStyle(1, 0);5. model.streetGrid.search(map.extent, streetHandler);6.}
8.private function streetHandler(street:Street, data:Object = null):void{9. for each(var path:Array in street.shpPolyline.paths){10. var index:int = 0;11. var lastX:Number = toScreenX(path[index++]);12. var lastY:Number = toScreenY(path[index++]);13. graphics.moveTo(lastX, lastY);14. while(index < path.length){15. var currX:Number = toScreenX(path[index++]);16. var currY:Number = toScreenY(path[index++]);17. if( currX !== lastX || currY !== lastY){18. graphics.lineTo(currX, currY);19. lastX = currX;20. lastY = currY; 21. }22. }23. }24.}
1.override protected function updateLayer():void{2. const model:Model = Model.instance;3. graphics.clear();4. graphics.lineStyle(1, 0);5. model.streetGrid.search(map.extent, streetHandler);6.}
8.private function streetHandler(street:Street, data:Object = null):void{9. for each(var path:Array in street.shpPolyline.paths){10. var index:int = 0;11. var lastX:Number = toScreenX(path[index++]);12. var lastY:Number = toScreenY(path[index++]);13. graphics.moveTo(lastX, lastY);14. while(index < path.length){15. var currX:Number = toScreenX(path[index++]);16. var currY:Number = toScreenY(path[index++]);17. if( currX !== lastX || currY !== lastY){18. graphics.lineTo(currX, currY);19. lastX = currX;20. lastY = currY; 21. }22. }23. }24.}
DemoStreetTrace
When Will I Use This ?
Q&Ahttp://thunderheadxpler.blogspot.com