Skip to content
Permalink
Browse files
Support tags-on-relation multipolygons
  • Loading branch information
systemed committed Mar 24, 2017
1 parent 380551d commit d53e6c5
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 21 deletions.
@@ -239,12 +239,14 @@ package net.systemeD.halcyon {
// Copy tags object, and add states
var multis:Array=entity.findParentRelationsOfType('multipolygon','outer');
var tags:Object;
if (!entity.hasTags() && multis.length>0) {
var isArea:Boolean = Way(entity).isArea();
if (!entity.hasInterestingTags() && multis.length>0) {
tags = multis[0].getTagsCopy();
isArea = true;
} else {
tags = entity.getTagsCopy();
}
setStateClass('area', Way(entity).isArea());
setStateClass('area', isArea);
setStateClass('background', paint.isBackground);
setStateClass('tiger', (entity.isUneditedTiger() && Globals.vars.highlightTiger));
tags=applyStateClasses(tags);
@@ -393,6 +393,12 @@ package net.systemeD.halcyon.connection {
return parents[entity] == true;
}

/** Get all entities that the user might want to edit after clicking this.
* Usually just the entity itself, but could also include related multipolygon relations. */
public function getRelatedEntities():Array {
return [this];
}

/** Returns all relations that this Entity is part of, as array of {relation, position, role}, sorted by position. */
public function get memberships():Array {
var list:Array=[];
@@ -157,6 +157,14 @@ package net.systemeD.halcyon.connection {
return relTags["type"] ? relTags["type"] : getType();
}

public function hasKeysOtherThanType():Boolean {
// used for detecting old-style vs new-style multipolygons
for (var key:String in getTagsHash()) {
if (key!='type' && key!='created_by' && key!='source') { return false; }
}
return true;
}

private function getSignificantName(entity:Entity):String {
if (!entity.loaded || (entity is Relation)) return '';

@@ -144,6 +144,19 @@ package net.systemeD.halcyon.connection {
markDirty();
}

override public function getRelatedEntities():Array {
var multis:Array = findParentRelationsOfType('multipolygon');
var related:Array = [this];
var wayHasInteresting:Boolean = hasInterestingTags();
for each (var multi:Relation in multis) {
// if an old-style multipolygon, add to end of list
if (wayHasInteresting && multi.hasKeysOtherThanType()) { related.push(multi); }
// if a new-style multipolygon, add to start of list
else { related.unshift(multi); }
}
return related;
}

/** Merges another way into this one, removing the other one. */
public function mergeWith(way:Way,topos:int,frompos:int, performAction:Function):void {
performAction(new MergeWaysAction(this, way, topos, frompos));
@@ -122,9 +122,15 @@
enabled="{editorStack is TabNavigator && stack.selectedIndex==0}" />
</mx:HBox>

<mx:Label id="entityDisplayID" click="new HistoryDialog().init(selectedEntity);" paddingLeft="4" paddingBottom="3">
<mx:htmlText><![CDATA[<i>No Selection</i>]]></mx:htmlText>
</mx:Label>
<mx:HBox width="100%">
<mx:Label id="entityDisplayID" click="new HistoryDialog().init(selectedEntity);" paddingLeft="4" paddingBottom="3">
<mx:htmlText><![CDATA[<i>No Selection</i>]]></mx:htmlText>
</mx:Label>
<mx:PopUpButton id="entitySelectButton" arrowButtonWidth="12" paddingLeft="0" paddingRight="0"
width="12" height="12" enabled="false"
creationComplete="{createEntityMenu(PopUpButton(event.target));}" />
</mx:HBox>

</mx:VBox>

<!-- Multiple selection -->
@@ -255,6 +261,7 @@
public var mapFeatures:MapFeatures;
public var controller:EditController;
private var selectedEntity:Entity;
private var relatedEntities:Array;
private var connection:Connection;
private var currentCategorySelector:CategorySelector;
private var categorySelectors:Object = {}; // hash of categorySelectors for each limitType
@@ -264,7 +271,10 @@
private var rowData:Object; // relation membership reference, needed so it's accessible from relation actions menu
public function setEntity(entities:Array, layer:MapPaint=null):void {
/** Set the entity for the tag viewer, and refresh all the UI
* If autoselect is true, then the tag viewer may choose to show a 'parent' multipolygon element instead
*/
public function setEntity(entities:Array, layer:MapPaint=null, autoselect:Boolean=true):void {
UIComponent.suspendBackgroundProcessing();
connection=null;
@@ -285,13 +295,23 @@
} else if (entities.length==1) {
// Single entity selected, so show tag panel
if (firstSelected!=null && selectedEntity!=firstSelected) {
firstSelected.addEventListener(Connection.TAG_CHANGED, tagChanged, false, 0, true);
var lastSelected:Entity = selectedEntity;
if (autoselect) {
relatedEntities = firstSelected.getRelatedEntities();
selectedEntity = relatedEntities[0];
} else {
selectedEntity = firstSelected;
}
selectedEntity=firstSelected;
if (lastSelected!=selectedEntity) { relatedEntities[0].addEventListener(Connection.TAG_CHANGED, tagChanged, false, 0, true); }
updateEntityMenuDataProvider();
connection=firstSelected.connection;
if (entityDisplayID!=null) { setupAdvanced(firstSelected); }
if (entityDisplayID!=null) {
setupAdvanced(selectedEntity);
updateEntityDisplay(selectedEntity);
}
if (selectedEntity is Relation) { stack.addChild(membersVBox); }
else if (membersVBox.parent==stack) { stack.removeChild(membersVBox); }
if (selectedEntity is Marker && connection is BugConnection) {
bugPanelContents.init(selectedEntity, BugConnection(connection));
sidebar.selectedChild = bugPanel;
@@ -468,7 +488,7 @@
private function limitType(entity:Entity):String {
if (entity is Node ) return "point";
else if (entity is Way ) return Way(entity).isArea() ? "area" : "line";
else if (entity is Relation) return "relation";
else if (entity is Relation) return Relation(entity).getRelationType()=='multipolygon' ? "area" : "relation";
return null;
}
@@ -661,10 +681,12 @@
stack.selectedChild=advancedContainer;
}
private function checkAdvanced():void {
if ( selectedEntity != null )
setupAdvanced(selectedEntity);
}
private function checkAdvanced():void {
if ( selectedEntity != null ) {
setupAdvanced(selectedEntity);
updateEntityDisplay(selectedEntity);
}
}
private var listeningToRelations:Array = [];
@@ -679,11 +701,35 @@
entityDisplayID.htmlText = entityText+": <b>"+entity.id+"</b> "+(entity.status ? entity.status : '');
}
}
[bindable] private var entityMenuList:ArrayCollection = new ArrayCollection([]);
// Create drop-down entity select menu (for multipolygons)
private function createEntityMenu(button:PopUpButton):void {
var menu:Menu = new Menu();
menu.dataProvider = entityMenuList;
button.popUp = menu;
menu.addEventListener("itemClick", selectEntityMenu);
}
// Update entries in entity select menu
private function updateEntityMenuDataProvider():void {
entityMenuList.removeAll();
for each (var e:Entity in relatedEntities) {
entityMenuList.addItem({ label: e.getType()+" "+e.id, data: e });
}
entitySelectButton.enabled = relatedEntities.length>1;
}
// An entity has been selected from the drop-down menu
private function selectEntityMenu(event:MenuEvent):void {
selectedEntity = event.item.data;
setEntity([selectedEntity],null,false);
}
private function setupAdvanced(entity:Entity):void {
if (!advancedTagGrid) advancedContainer.createComponentsFromDescriptors(); // if Flex hasn't created it, force it
advancedTagGrid.init(entity);
updateEntityDisplay(entity);
removeRelationListeners();
if ( entity == null ) {
@@ -962,8 +1008,10 @@
}
// remove tags from the current feature
// (but don't drop multipolygon tags)
if ( feature != null ) {
for each( var oldtag:Object in feature.tags ) {
if (oldtag["k"]=='type' && oldtag["v"]=='multipolygon' && selectedEntity is Relation) { continue; }
if ( editableTags.indexOf(oldtag["k"]) < 0 ) {
selectedEntity.setTag(oldtag["k"], null, action.push);
}
@@ -117,22 +117,25 @@ package net.systemeD.potlatch2.controller {
controller.dispatchEvent(new AttentionEvent(AttentionEvent.ALERT, null, "Couldn't make the multipolygon"));
return this;
}
var action:CompositeUndoableAction = new CompositeUndoableAction("Add to multipolygon");

// If relation exists, add any inners that aren't currently present
if (multi.relation) {
var action:CompositeUndoableAction = new CompositeUndoableAction("Add to multipolygon");
for each (inner in multi.inners) {
if (!multi.relation.hasMemberInRole(inner,'inner'))
multi.relation.appendMember(new RelationMember(inner,'inner'),action.push);
}
MainUndoStack.getGlobalStack().addAction(action);

// Otherwise, create whole new relation
// Otherwise, create whole new relation, and transfer the tags
} else {
var memberlist:Array=[new RelationMember(multi.outer,'outer')];
for each (inner in multi.inners)
memberlist.push(new RelationMember(inner,'inner'));
layer.connection.createRelation( { type: 'multipolygon' }, memberlist, MainUndoStack.getGlobalStack().addAction);
for each (inner in multi.inners) { memberlist.push(new RelationMember(inner,'inner')); }
var tags:Object = multi.outer.getTagsCopy();
tags['type'] = 'multipolygon';
for (var key:String in tags) { multi.outer.setTag(key, null, action.push); }
layer.connection.createRelation( tags, memberlist, action.push);
MainUndoStack.getGlobalStack().addAction(action);
}

return new SelectedWay(multi.outer);

0 comments on commit d53e6c5

Please sign in to comment.