}
}
- /** Download map data. Data is downloaded for the connection and the vector layers, where supported.
+ /** Download map data. Data is downloaded for the currently visible layers
* The bounding box for the download is taken from the current map edges.
*/
public function download():void {
this.dispatchEvent(new MapEvent(MapEvent.DOWNLOAD, {minlon:edge_l, maxlon:edge_r, maxlat:edge_t, minlat:edge_b} ));
for (var i:uint=0; i<paintContainer.numChildren; i++)
- getLayerAt(i).connection.loadBbox(edge_l,edge_r,edge_t,edge_b);
+ if(getLayerAt(i).visible == true) {
+ getLayerAt(i).connection.loadBbox(edge_l,edge_r,edge_t,edge_b);
+ }
}
// Handle mouse events on ways/nodes
public var name:String;
public var statusFetcher:StatusFetcher;
+ public var inlineStatus:Boolean = false;
protected var apiBaseURL:String;
protected var policyURL:String;
protected var params:Object;
// these are functions that the Connection implementation is expected to
// provide. This class has some generic helpers for the implementation.
+ /**
+ * Load data for the bounding box given. Usually called in response to pan / zoom requests
+ */
public function loadBbox(left:Number, right:Number,
top:Number, bottom:Number):void {
}
Number(nodeData.@lon),
Number(nodeData.@uid),
nodeData.@timestamp);
+ if ( inlineStatus ) { newNode.status = nodeData.@status; }
if ( singleEntityRequest ) {
// it's a revert request, so create/update the node
tags = parseTags(data.tag);
if ( way == null ) {
way=new Way(this, id, version, tags, true, nodelist, uid, timestamp)
+ if ( inlineStatus ) { way.status = data.@status; }
setWay(way,false);
createdEntities.push(way);
} else {
waycount++;
way.update(version, tags, true, true, nodelist, uid, timestamp);
+ if ( inlineStatus ) { way.status = data.@status; }
sendEvent(new EntityEvent(NEW_WAY, way), false);
}
}
/**
* XMLConnection provides all the methods required to connect to a live
* OSM server. See OSMConnection for connecting to a read-only .osm file
+ *
+ * @see OSMConnection
*/
public class XMLConnection extends XMLBaseConnection {
+ /**
+ * Create a new XML connection
+ * @param name The name of the connection
+ * @param api The url of the OSM API server, e.g. http://api06.dev.openstreetmap.org/api/0.6/
+ * @param policy The url of the flash crossdomain policy to load,
+ e.g. http://api06.dev.openstreetmap.org/api/crossdomain.xml
+ * @param initparams Any further parameters for the connection, such as the serverName
+ */
public function XMLConnection(name:String,api:String,policy:String,initparams:Object) {
super(name,api,policy,initparams);
this._map = map;
setState(new NoSelection());
this.tagViewer = tagViewer;
+ this.tagViewer.controller = this;
this.toolbox = toolbox;
this.toolbox.init(this);
this.maximiseFunction = Globals.vars.flashvars["maximise_function"];
<sidepanel:BackgroundPanel id="backgroundPanelContents" width="100%"/>
</mx:VBox>
+ <!-- merge tags from background layer -->
+
+ <mx:VBox id="backgroundMergePanel" width="100%" height="100%" horizontalScrollPolicy="off" styleName="dndPanelVbox">
+ <sidepanel:BackgroundMergePanel id="backgroundMergePanelContents" width="100%" />
+ </mx:VBox>
+
</mx:ViewStack>
<fx:Script><![CDATA[
import net.systemeD.halcyon.connection.*;
import net.systemeD.halcyon.MapPaint;
+ import net.systemeD.potlatch2.EditController;
import net.systemeD.potlatch2.mapfeatures.*;
import net.systemeD.potlatch2.utils.*;
import net.systemeD.controls.CollapsiblePanel;
[Bindable] private var editorStack:Container;
public var mapFeatures:MapFeatures;
+ public var controller:EditController;
private var selectedEntity:Entity;
private var connection:Connection;
private var currentCategorySelector:CategorySelector;
sidebar.selectedChild = tagsPanel;
}
+ } else if (entities.length==2
+ && xor(entities[0].connection is SnapshotConnection, entities[1].connection is SnapshotConnection)
+ && xor(!controller.map.getLayerForEntity(entities[0]).isBackground, !controller.map.getLayerForEntity(entities[1]).isBackground) ) {
+ backgroundMergePanelContents.init(entities);
+ sidebar.selectedChild = backgroundMergePanel;
+
} else if(isMultipleEditable(entities)) {
selectedEntity = new EntityCollection(entities);
selectedEntity.addEventListener(Connection.TAG_CHANGED, tagChanged);
UIComponent.resumeBackgroundProcessing();
}
+ private function xor(a:Boolean, b:Boolean):Boolean {
+ return ( a || b) && !(a && b);
+ }
+
private function refreshFeatureIcon():void {
var oldFeature:Feature = feature;
feature = selectedEntity == null ? null : mapFeatures.findMatchingFeature(selectedEntity);
Security.loadPolicyFile(String(set.policyfile));
}
+ // Check for any bounds for the vector layer. Obviously won't kick in during subsequent panning
+ var validBbox:Boolean = false;
+ if (set.@minlon && String(set.@minlon) != '') {
+ if (((_map.edge_l>set.@minlon && _map.edge_l<set.@maxlon) ||
+ (_map.edge_r>set.@minlon && _map.edge_r<set.@maxlon) ||
+ (_map.edge_l<set.@minlon && _map.edge_r>set.@maxlon)) &&
+ ((_map.edge_b>set.@minlat && _map.edge_b<set.@maxlat) ||
+ (_map.edge_t>set.@minlat && _map.edge_t<set.@maxlat) ||
+ (_map.edge_b<set.@minlat && _map.edge_t>set.@maxlat))) {
+ validBbox = true;
+ } else {
+ validBbox = false; // out of bounds
+ }
+ } else {
+ validBbox = true; // global set
+ }
+
if (set.@disabled == "true") {
- } else {
+ // Don't do anything with it. The "disabled" attribute allows examples to appear in the config file
+ } else if (validBbox) {
var name:String = (set.name == undefined) ? null : String(set.name);
var loader:String = set.loader;
dispatchEvent(new Event("layers_changed"));
}, false);
} else {
- trace("configured but not loaded isn't supported yet");
+ trace("VectorBackgrounds: configured but not loaded isn't supported yet");
}
} else {
- trace("AutoVectorBackground: no url for GPXImporter");
+ trace("VectorBackgrounds: no url for GPXImporter");
}
break;
bugLoader.load();
}
} else {
- trace("AutoVectorBackground: error with BugLoader");
+ trace("VectorBackgrounds: error with BugLoader");
}
break;
bikeShopLoader.load();
}
} else {
- trace("AutoVectorBackground: no url for BikeShopLoader");
+ trace("VectorBackgrounds: no url for BikeShopLoader");
}
break;
case "SnapshotLoader":
if (set.url) {
name ||= 'Snapshot Server'
- var snapshotLoader:SnapshotLoader = new SnapshotLoader(_map, String(set.url), name);
+ var snapshotLoader:SnapshotLoader = new SnapshotLoader(_map, String(set.url), name, String(set.style));
if (set.@loaded == "true") {
snapshotLoader.load();
}
} else {
- trace("VectorBackground: no url for SnapshotLoader");
+ trace("VectorBackgrounds: no url for SnapshotLoader");
}
break;
default:
- trace("AutoVectorBackground: unknown loader");
+ trace("VectorBackgrounds: unknown loader: " + loader);
}
}
});
import flash.geom.Point;
import flash.ui.Keyboard;
import net.systemeD.potlatch2.EditController;
+ import net.systemeD.halcyon.MapPaint;
import net.systemeD.halcyon.connection.*;
import net.systemeD.halcyon.connection.actions.*;
private var downX:Number;
private var downY:Number;
private var dragstate:uint=NOT_MOVED;
+ private var initialMouseEvent:MouseEvent;
+ private var wayList:Array;
/** Not used? */
private const NOT_DRAGGING:uint=0;
private const DRAGGING:uint=2;
/** Start the drag by recording the dragged way, where it started, and when. */
- public function DragSelection(sel:Array, event:MouseEvent) {
+ public function DragSelection(sel:Array, event:MouseEvent, ways:Array = null) {
selection = sel.concat();
downX = event.localX;
downY = event.localY;
+ wayList = ways;
enterTime = (new Date()).getTime();
+ initialMouseEvent = event;
}
/** Handle dragging and end drag events. Filters out very short or quick drags. */
/** Abort dragging if ESC pressed. */
override public function processKeyboardEvent(event:KeyboardEvent):ControllerState {
+ if (event.keyCode==Keyboard.SPACE) { return cycleAllWays(initialMouseEvent); }
if (event.keyCode==Keyboard.ESCAPE) {
for each (var entity:Entity in selection) {
entity.dispatchEvent(new EntityDraggedEvent(Connection.ENTITY_DRAGGED, entity, 0, 0));
dragstate=NOT_MOVED;
}
+ private function cycleAllWays(event:MouseEvent):ControllerState {
+ trace("cycleAllWays");
+ if (!(downX && downY) || (wayList && wayList.length<2) || selection.length != 1) { return this; }
+ trace("cycleAllWays2");
+ if (!wayList) {
+ wayList=selection
+ for each (var l:MapPaint in controller.map.getLayers()) {
+ trace("Layer "+l.connection.name);
+ trace(l.findWaysAtPoint(event.stageX, event.stageY).length);
+ wayList = wayList.concat(l.findWaysAtPoint(event.stageX, event.stageY,selection[0]));
+ }
+ }
+ for each (var way:Way in wayList) {
+ trace(way + "::" + way.connection.name);
+ }
+ wayList=wayList.slice(1).concat(wayList[0]);
+ // Find the new way's index of the currently "selected" node, to facilitate keyboard navigation
+ return new DragSelection([wayList[0]], event, wayList);
+ }
+
/** Highlight the dragged selection. */
override public function enterState():void {
for each (var entity:Entity in selection) {
var d:DragWayNode=new DragWayNode(firstSelected as Way, -1, event, true);
d.forceDragStart();
return d;
- } else if ( event.type == MouseEvent.MOUSE_DOWN && event.ctrlKey && entity && entity!=firstSelected && paint==layer) {
+ } else if ( event.type == MouseEvent.MOUSE_DOWN && event.ctrlKey && entity && entity!=firstSelected) {
// multiple selection
return new SelectedMultiple([firstSelected,entity],layer);
} else if ( event.type == MouseEvent.MOUSE_UP && focus==firstSelected ) {
--- /dev/null
+package net.systemeD.potlatch2.panels {
+
+ import mx.controls.Label;
+ import mx.controls.dataGridClasses.*;
+ import net.systemeD.potlatch2.panels.BackgroundMergePanel;
+
+ public class BackgroundMergeFieldComponent extends Label {
+
+ override public function set data(value:Object):void
+ {
+ if(value != null)
+ {
+ super.data = value;
+ if (listData.label != ' ') { // yes, a space. No, neither null nor empty string. I hate you, adobe
+ textField.background = true;
+ textField.backgroundColor = BackgroundMergePanel(listData.owner.parent).getColorFor(listData.rowIndex);
+ } else {
+ textField.background = false;
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Background Merge Panel
+-->
+
+<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" height="100%">
+ <mx:Text id="backgroundMergePanelText" text="Review and Merge tags from the Background layer" width="100%" styleName="helpInfo" />
+ <mx:DataGrid editable="false" id="backgroundPanelDG" width="100%" height="50%">
+ <mx:columns>
+ <mx:DataGridColumn editable="false" dataField="k" headerText="Key" />
+ <mx:DataGridColumn editable="false" dataField="e" headerText="OSM value" />
+ <mx:DataGridColumn editable="false" headerText="Merge" width="50" textAlign="center">
+ <mx:itemRenderer>
+ <mx:Component>
+ <mx:HBox horizontalAlign="center" verticalAlign="middle">
+ <mx:Button label="<<" visible="{parentDocument.buttonVisible(data.b, data.e)}" click="parentDocument.mergeForKey(data.k);" />
+ </mx:HBox>
+ </mx:Component>
+ </mx:itemRenderer>
+ </mx:DataGridColumn>
+ <mx:DataGridColumn editable="false" itemRenderer="net.systemeD.potlatch2.panels.BackgroundMergeFieldComponent" dataField="b" headerText="Background value" />
+ </mx:columns>
+ </mx:DataGrid>
+ <mx:ViewStack id="statusStack" resizeToContent="true" width="100%">
+ <mx:VBox id="empty" />
+ <mx:VBox id="not_complete">
+ <mx:Text text="All the data copied to the main layer? Click 'complete'!" />
+ <mx:Button label="Complete" click="markComplete()"/>
+ </mx:VBox>
+ <mx:VBox id="complete">
+ <mx:Text text="This feature has been marked as complete. If this is wrong, press the button below." />
+ <mx:Button label="Not complete" click="markNotComplete()"/>
+ </mx:VBox>
+ </mx:ViewStack>
+ <mx:Script><![CDATA[
+
+ import net.systemeD.halcyon.connection.*;
+ import net.systemeD.halcyon.MapPaint;
+ import net.systemeD.potlatch2.utils.SnapshotConnection;
+
+ import mx.collections.*;
+
+ private var editableEntity:Entity;
+ private var backgroundEntity:Entity;
+ private var tagDataProvider:ArrayCollection;
+
+ public function init(entities:Array):void {
+ if ( tagDataProvider == null ) {
+ tagDataProvider = new ArrayCollection();
+ backgroundPanelDG.dataProvider = tagDataProvider;
+ }
+
+ if (parentDocument.controller.map.getLayerForEntity(entities[0]).isBackground) {
+ backgroundEntity = entities[0];
+ editableEntity = entities[1];
+ } else {
+ backgroundEntity = entities[1];
+ editableEntity = entities[0];
+ }
+ backgroundEntity.addEventListener(Connection.STATUS_CHANGED, statusEvent, false, 0, true);
+ setStatusStack();
+ editableEntity.addEventListener(Connection.TAG_CHANGED, tagChanged, false, 0, true);
+ updateTagDataProvider();
+ }
+
+ private function updateTagDataProvider():void {
+ var tag:Tag;
+ var keys:Array = [];
+
+ tagDataProvider.removeAll();
+
+ for each (tag in backgroundEntity.getTagArray() ) {
+ keys.push(tag.key);
+ }
+
+ for each (tag in editableEntity.getTagArray() ) {
+ keys.push(tag.key);
+ }
+
+ keys=keys.filter(function(k:*, i:int, arr:Array):Boolean { return arr.indexOf(k) == i } ); // remove duplicates
+ keys.sort();
+
+ for each (var key:String in keys) {
+ tagDataProvider.addItem({k:key, e:editableEntity.getTag(key), b:backgroundEntity.getTag(key)});
+ }
+ backgroundPanelDG.invalidateList();
+ }
+
+ private function tagChanged(e:Event):void {
+ updateTagDataProvider();
+ }
+
+ public function buttonVisible(b:String, e:String):Boolean {
+ if (b != null && b != e) {
+ return true;
+ }
+ return false;
+ }
+
+ public function mergeForKey(key:String):void {
+ editableEntity.setTag(key, backgroundEntity.getTag(key), MainUndoStack.getGlobalStack().addAction);
+ }
+
+ // Don't call this for things you don't want coloured in. Like for empty tags.
+ public function getColorFor(i:int):int {
+ if (tagDataProvider[i].e == tagDataProvider[i].b) {
+ return 0xDDFFDD; // matching, green
+ } else if (tagDataProvider[i].e == null) {
+ return 0xDDDDFF; // new value, blue
+ } else if (tagDataProvider[i].b) {
+ return 0xFFDDDD; // conflicting, red
+ }
+ return NaN; // which is interpretted as black
+ }
+
+ private function statusEvent(e:Event):void {
+ setStatusStack();
+ }
+
+ private function setStatusStack():void {
+ switch (backgroundEntity.status) {
+ case 'incomplete':
+ statusStack.selectedChild = not_complete;
+ break;
+ case 'complete':
+ statusStack.selectedChild = complete;
+ break;
+ default:
+ statusStack.selectedChild = empty;
+ }
+ }
+
+ private function markComplete():void {
+ if (backgroundEntity.connection is SnapshotConnection) {
+ SnapshotConnection(backgroundEntity.connection).markComplete(backgroundEntity);
+ }
+ }
+
+ private function markNotComplete():void {
+ if (backgroundEntity.connection is SnapshotConnection) {
+ SnapshotConnection(backgroundEntity.connection).markNotComplete(backgroundEntity);
+ }
+ }
+ ]]>
+ </mx:Script>
+</mx:VBox>
\ No newline at end of file
<mx:DataGridColumn editable="false" dataField="value" headerText="value" />
</mx:columns>
</mx:DataGrid>
- <mx:Text text="All the data copied to the main layer? Click 'complete'!" />
- <mx:Button label="Complete" click="markComplete()"/>
+ <mx:ViewStack id="statusStack" resizeToContent="true" width="100%">
+ <mx:VBox id="empty" />
+ <mx:VBox id="not_complete">
+ <mx:Text text="All the data copied to the main layer? Click 'complete'!" />
+ <mx:Button label="Complete" click="markComplete()"/>
+ </mx:VBox>
+ <mx:VBox id="complete">
+ <mx:Text text="This feature has been marked as complete. If this is wrong, press the button below." />
+ <mx:Button label="Not complete" click="markNotComplete()"/>
+ </mx:VBox>
+ </mx:ViewStack>
<fx:Script><![CDATA[
import net.systemeD.halcyon.connection.*;
private var layer:MapPaint;
public function init(entity:Entity, layer:MapPaint):void {
- this.layer = layer;
- if ( tagDataProvider == null ) {
- tagDataProvider = new ArrayCollection();
- backgroundPanelDG.dataProvider = tagDataProvider;
- }
-
- selectedEntity=entity;
- updateTagDataProvider();
+ this.layer = layer;
+ if ( tagDataProvider == null ) {
+ tagDataProvider = new ArrayCollection();
+ backgroundPanelDG.dataProvider = tagDataProvider;
+ }
+
+ selectedEntity=entity;
+ selectedEntity.addEventListener(Connection.STATUS_CHANGED, statusEvent, false, 0, true);
+ setStatusStack();
+ updateTagDataProvider();
}
private function updateTagDataProvider():void {
- tagDataProvider.removeAll();
- if (selectedEntity==null) { return; }
- var tags:Array = selectedEntity.getTagArray();
- tags.sortOn("key");
- for each(var tag:Tag in tags) { tagDataProvider.addItem(tag); }
+ tagDataProvider.removeAll();
+ if (selectedEntity==null) { return; }
+ var tags:Array = selectedEntity.getTagArray();
+ tags.sortOn("key");
+ for each(var tag:Tag in tags) { tagDataProvider.addItem(tag); }
+ }
+
+ private function statusEvent(e:Event):void {
+ setStatusStack();
+ }
+
+ private function setStatusStack():void {
+ switch (selectedEntity.status) {
+ case 'incomplete':
+ statusStack.selectedChild = not_complete;
+ break;
+ case 'complete':
+ statusStack.selectedChild = complete;
+ break;
+ default:
+ statusStack.selectedChild = empty;
+ }
}
private function markComplete():void {
- if (selectedEntity.connection is SnapshotConnection) {
- SnapshotConnection(selectedEntity.connection).markComplete(selectedEntity);
- }
+ if (selectedEntity.connection is SnapshotConnection) {
+ SnapshotConnection(selectedEntity.connection).markComplete(selectedEntity);
+ }
+ }
+
+ private function markNotComplete():void {
+ if (selectedEntity.connection is SnapshotConnection) {
+ SnapshotConnection(selectedEntity.connection).markNotComplete(selectedEntity);
+ }
}
]]>
</fx:Script>
this.bikeShopBaseURL = url;
this.name = name;
this.connection = new BikeShopConnection(name,url,bikeShopBaseURL+"crossdomain.xml",null);
+ _layer = map.addLayer(connection, STYLESHEET);
+ _layer.visible = false;
}
public function load():void {
- if (!_layer) {
- _layer = map.addLayer(connection, STYLESHEET);
- }
+ _layer.visible = true;
connection.loadBbox(map.edge_l, map.edge_r, map.edge_t, map.edge_b);
}
}
this.name = name;
this.bugDetailsURL = details;
connection = new BugConnection(name, url, bugApiKey, details);
+ _layer = map.addLayer(connection, STYLESHEET, true, true);
+ _layer.visible = false;
}
public function load():void {
- if (!_layer) {
- _layer = map.addLayer(connection, STYLESHEET, true, true);
- }
+ _layer.visible = true;
connection.loadBbox(map.edge_l, map.edge_r, map.edge_t, map.edge_b);
}
}
import flash.events.Event;
import flash.net.*;
+ /**
+ * A connection to a Snapshot server. A Snapshot server serves OSM map requests and can also
+ * track the "status" of an entity. Most other types of XMLConnection requests will fail. See
+ * http://www.github.com/gravitystorm/snapshot-server for example code based on the database
+ * structure created by osmosis pgsnapshot schema.
+ */
+
public class SnapshotConnection extends XMLConnection {
public function SnapshotConnection(cname:String,api:String,policy:String,initparams:Object=null) {
super(cname,api,policy,initparams);
+ inlineStatus = true;
}
- /** Send a "complete" call to the server, and remove it from the current layer */
+ // As it stands, the following two functions could be refactored further.
+
+ /**
+ * Post a status update call to the server and update entity.status if successful.
+ */
public function markComplete(entity:Entity):void {
+ var urlReq:URLRequest;
+
+ if (entity is Node) {
+ var node:Node = Node(entity);
+ if (node == getNode(node.id)) { // confirm it's from this connection
+ makeRequest(entity, 'complete');
+ }
+
+ } else if (entity is Way) {
+ var way:Way = Way(entity);
+ if (way == getWay(way.id)) { // confirm it's from this connection
+ makeRequest(entity, 'complete');
+ }
+ }
+ }
+
+ /**
+ * Send a "complete" call to the server and update entity.status if successful.
+ */
+ public function markNotComplete(entity:Entity):void {
+ var urlReq:URLRequest;
+
if (entity is Node) {
- var node:Node = Node(entity);
- if (node == getNode(node.id)) { // confirm it's from this connection
- var urlReq:URLRequest = new URLRequest(apiBaseURL+"node/"+node.id+"/complete");
- urlReq.method = "POST";
- urlReq.data = ' ';
- urlReq.contentType = "application/xml";
- urlReq.requestHeaders = [ new URLRequestHeader("X_HTTP_METHOD_OVERRIDE", "PUT"),
- new URLRequestHeader("X-Error-Format", "XML") ];
- var loader:URLLoader = new URLLoader();
- loader.addEventListener(Event.COMPLETE, function(e:Event):void { killNode(node.id) });
- loader.load(urlReq);
- }
+ var node:Node = Node(entity);
+ if (node == getNode(node.id)) { // confirm it's from this connection
+ makeRequest(entity, 'incomplete');
+ }
} else if (entity is Way) {
- var way:Way = Way(entity);
- trace("not implemented");
+ var way:Way = Way(entity);
+ if (way == getWay(way.id)) { // confirm it's from this connection
+ makeRequest(entity, 'incomplete');
+ }
}
}
+ private function makeRequest(entity:Entity, status:String):void {
+ var urlReq:URLRequest = new URLRequest(apiBaseURL+entity.getType()+"/"+entity.id+"/status");
+ urlReq.method = "POST";
+ urlReq.data = status;
+ var loader:URLLoader = new URLLoader();
+ loader.addEventListener(Event.COMPLETE, function(e:Event):void { updateStatus(entity, status) });
+ loader.load(urlReq);
+ }
+
+ private function updateStatus(e:Entity, s:String):void {
+ e.setStatus(s);
+ }
+
}
}
\ No newline at end of file
import net.systemeD.halcyon.MapPaint;
import net.systemeD.potlatch2.utils.SnapshotConnection;
+ /**
+ * Loads a Snapshot layer. Uses lazy-loading such that only when the load() function is
+ * called will the layer be created and added to the map
+ *
+ * @see SnapShotConnection
+ */
public class SnapshotLoader {
private var map:Map;
private var _layer:MapPaint;
- private static const STYLESHEET:String="stylesheets/wireframe.css"; //TODO take from xml
+ private static const STYLESHEET:String="stylesheets/snapshot.css";
private var connection:SnapshotConnection;
+ private var _stylesheet:String;
-
- public function SnapshotLoader(map:Map, url:String, name:String):void {
+ /**
+ * Create a new SnapshotLoader
+ * @param map The map object to attach the layer to
+ * @param url The url of the snapshot server. This should be to the api base and
+ end in a forward slash, e.g. http://example.com/snapshot/api/
+ * @param name The name to give to the layer/connection
+ * @param stylesheet The url of the stylesheet to use for styling the layer
+ */
+ public function SnapshotLoader(map:Map, url:String, name:String, stylesheet:String = null):void {
this.map = map;
connection = new SnapshotConnection(name, url, '');
+ _stylesheet = (stylesheet && stylesheet != '') ? stylesheet : STYLESHEET;
+ _layer = map.addLayer(connection, _stylesheet, true, true);
+ _layer.visible = false;
}
+ /**
+ * Load the layer.
+ * Call this the first time you wish to load the layer. After this it will respond
+ * automatically to pan / zooming of the associated Map
+ */
public function load():void {
- if (!_layer) {
- _layer = map.addLayer(connection, STYLESHEET);
- }
+ _layer.visible = true;
connection.loadBbox(map.edge_l, map.edge_r, map.edge_t, map.edge_b);
}
}
--- /dev/null
+/*
+
+ Stylesheet that does simple wireframe display
+
+*/
+
+way :hover { z-index: 2; width: 1; color: yellow; }
+way :selected { z-index: 2; width: 2; color: yellow; }
+way !:drawn { z-index:10; width: 1; color: black; }
+
+node :selectedway { z-index: 8; icon-image: square; icon-width: 6; color: green; }
+node :hoverway { z-index: 9; icon-image: square; icon-width: 6; color: blue; }
+node :selected { z-index: 9; icon-image: square; icon-width: 6; color: red; casing-color: black; casing-width: 1; }
+node !:drawn :poi { z-index: 2; icon-image: square; icon-width: 4; color: green; casing-color: black; casing-width: 1; }
+node !:drawn :hasTags { z-index: 9; icon-image: circle; icon-width: 3; color: black; }
+node :hasTags :selectedway { z-index: 9; icon-image: square; icon-width: 8; color: black; layer: 5; }
+
+way[_status=incomplete]::statushighlight { z-index: 0; width: 10; color: #d95f02; }
+way[_status=complete]::statushighlight { z-index: 0; width: 10; color: #1b9e77; opacity: 0.4; }
+node[_status=incomplete]::statushighlight :hasTags { z-index: 0; icon-image: square; icon-width: 10; color: #d95f02; }
+node[_status=complete]::statushighlight :hasTags { z-index: 0; icon-image: square; icon-width: 10; color: #1b9e77; opacity: 0.4; }
+
+
+
<url>http://80.242.147.84/osmbugs/api/</url>
<apikey>e4d47b6b8c26e822a62d747b802f98ac</apikey>
</set>
- <set>
+ <set minlat="49.8" minlon="-9" maxlat="61.1" maxlon="1.9">
<name>Bike Shop Locator - Missing Shops</name>
<loader>BikeShopLoader</loader>
<url>http://shaunmcdonald.dev.openstreetmap.org/bike-shop-locator/</url>
<!-- doesn't need a URL -->
</set>
<set disabled="true">
- <name>A particular GPX file</name>
- <loader>GPXImporter</loader>
- <policyfile>http://gravitystorm.dev.openstreetmap.org/gpx/crossdomain.xml</policyfile>
- <url>http://gravitystorm.dev.openstreetmap.org/gpx/112.gpx</url>
+ <name>CNXC</name>
+ <loader>SnapshotLoader</loader>
+ <policyfile>http://localhost:3000/crossdomain.xml</policyfile>
+ <url>http://localhost:3000/api/</url>
</set>
-</vectors>
\ No newline at end of file
+</vectors>