forked from MapComplete/MapComplete
		
	Refactoring of import button, various improvements
This commit is contained in:
		
							parent
							
								
									cabbdf96db
								
							
						
					
					
						commit
						a095af4f18
					
				
					 17 changed files with 527 additions and 328 deletions
				
			
		
							
								
								
									
										102
									
								
								Logic/Osm/Actions/CreateMultiPolygonWithPointReuseAction.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								Logic/Osm/Actions/CreateMultiPolygonWithPointReuseAction.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,102 @@ | |||
| import {OsmCreateAction} from "./OsmChangeAction"; | ||||
| import {Tag} from "../../Tags/Tag"; | ||||
| import {Changes} from "../Changes"; | ||||
| import {ChangeDescription} from "./ChangeDescription"; | ||||
| import FeaturePipelineState from "../../State/FeaturePipelineState"; | ||||
| import FeatureSource from "../../FeatureSource/FeatureSource"; | ||||
| import CreateNewWayAction from "./CreateNewWayAction"; | ||||
| import CreateWayWithPointReuseAction, {MergePointConfig} from "./CreateWayWithPointReuseAction"; | ||||
| import {And} from "../../Tags/And"; | ||||
| import {TagUtils} from "../../Tags/TagUtils"; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * More or less the same as 'CreateNewWay', except that it'll try to reuse already existing points | ||||
|  */ | ||||
| export default class CreateMultiPolygonWithPointReuseAction extends OsmCreateAction { | ||||
|     private readonly _tags: Tag[]; | ||||
|     public newElementId: string = undefined; | ||||
|     public newElementIdNumber: number  = undefined; | ||||
|     private readonly createOuterWay: CreateWayWithPointReuseAction | ||||
|     private readonly createInnerWays : CreateNewWayAction[] | ||||
| private readonly geojsonPreview: any; | ||||
|     private readonly theme: string; | ||||
|     private readonly changeType: "import" | "create" | string; | ||||
|     constructor(tags: Tag[], | ||||
|                 outerRingCoordinates: [number, number][], | ||||
|                 innerRingsCoordinates:  [number, number][][], | ||||
|                 state: FeaturePipelineState, | ||||
|                 config: MergePointConfig[], | ||||
|                 changeType: "import" | "create" | string | ||||
|     ) { | ||||
|         super(null,true); | ||||
|         this._tags = [...tags, new Tag("type","multipolygon")]; | ||||
|         this.changeType = changeType; | ||||
|         this.theme = state.layoutToUse.id | ||||
|         this. createOuterWay = new CreateWayWithPointReuseAction([], outerRingCoordinates, state, config) | ||||
|         this. createInnerWays = innerRingsCoordinates.map(ringCoordinates =>  | ||||
|             new CreateNewWayAction([],  | ||||
|             ringCoordinates.map(([lon, lat] )=> ({lat, lon})),  | ||||
|             {theme: state.layoutToUse.id})) | ||||
|          | ||||
|         this.geojsonPreview =  { | ||||
|             type: "Feature", | ||||
|             properties: TagUtils.changeAsProperties(new And(this._tags).asChange({})), | ||||
|             geometry:{ | ||||
|                 type: "Polygon", | ||||
|                 coordinates: [ | ||||
|                     outerRingCoordinates, | ||||
|                     ...innerRingsCoordinates | ||||
|                 ] | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public async getPreview(): Promise<FeatureSource> { | ||||
|         const outerPreview = await this.createOuterWay.getPreview() | ||||
|         outerPreview.features.data.push({ | ||||
|             freshness: new Date(), | ||||
|             feature: this.geojsonPreview | ||||
|         }) | ||||
|        return outerPreview | ||||
|     } | ||||
| 
 | ||||
|     protected async CreateChangeDescriptions(changes: Changes): Promise<ChangeDescription[]> { | ||||
|         console.log("Running CMPWPRA") | ||||
|         const descriptions: ChangeDescription[] = [] | ||||
|         descriptions.push(...await this.createOuterWay.CreateChangeDescriptions(changes)); | ||||
|         for (const innerWay of this.createInnerWays) { | ||||
|             descriptions.push(...await innerWay.CreateChangeDescriptions(changes)) | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         this.newElementIdNumber = changes.getNewID(); | ||||
|         this.newElementId = "relation/"+this.newElementIdNumber | ||||
|         descriptions.push({ | ||||
|             type:"relation", | ||||
|             id: this.newElementIdNumber, | ||||
|             tags: new And(this._tags).asChange({}), | ||||
|             meta: { | ||||
|                 theme: this.theme, | ||||
|                 changeType:this.changeType | ||||
|             }, | ||||
|             changes: { | ||||
|                 members: [ | ||||
|                     { | ||||
|                         type: "way", | ||||
|                         ref: this.createOuterWay.newElementIdNumber, | ||||
|                         role: "outer" | ||||
|                     }, | ||||
|                     // @ts-ignore
 | ||||
|                     ...this.createInnerWays.map(a => ({type: "way", ref: a.newElementIdNumber, role: "inner"})) | ||||
|                 ] | ||||
|             } | ||||
|         }) | ||||
|          | ||||
|          | ||||
|         return descriptions | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|  | @ -1,12 +1,12 @@ | |||
| import {Tag} from "../../Tags/Tag"; | ||||
| import OsmChangeAction from "./OsmChangeAction"; | ||||
| import OsmChangeAction, {OsmCreateAction} from "./OsmChangeAction"; | ||||
| import {Changes} from "../Changes"; | ||||
| import {ChangeDescription} from "./ChangeDescription"; | ||||
| import {And} from "../../Tags/And"; | ||||
| import {OsmWay} from "../OsmObject"; | ||||
| import {GeoOperations} from "../../GeoOperations"; | ||||
| 
 | ||||
| export default class CreateNewNodeAction extends OsmChangeAction { | ||||
| export default class CreateNewNodeAction extends OsmCreateAction { | ||||
| 
 | ||||
|     /** | ||||
|      * Maps previously created points onto their assigned ID, to reuse the point if uplaoded | ||||
|  | @ -121,7 +121,6 @@ export default class CreateNewNodeAction extends OsmChangeAction { | |||
|             reusedPointId = this._snapOnto.nodes[index + 1] | ||||
|         } | ||||
|         if (reusedPointId !== undefined) { | ||||
|             console.log("Reusing an existing point:", reusedPointId) | ||||
|             this.setElementId(reusedPointId) | ||||
|             return [{ | ||||
|                 tags: new And(this._basicTags).asChange(properties), | ||||
|  | @ -133,7 +132,6 @@ export default class CreateNewNodeAction extends OsmChangeAction { | |||
| 
 | ||||
|         const locations = [...this._snapOnto.coordinates] | ||||
|         locations.forEach(coor => coor.reverse()) | ||||
|         console.log("Locations are: ", locations) | ||||
|         const ids = [...this._snapOnto.nodes] | ||||
| 
 | ||||
|         locations.splice(index + 1, 0, [this._lon, this._lat]) | ||||
|  |  | |||
|  | @ -1,12 +1,13 @@ | |||
| import {ChangeDescription} from "./ChangeDescription"; | ||||
| import OsmChangeAction from "./OsmChangeAction"; | ||||
| import {OsmCreateAction} from "./OsmChangeAction"; | ||||
| import {Changes} from "../Changes"; | ||||
| import {Tag} from "../../Tags/Tag"; | ||||
| import CreateNewNodeAction from "./CreateNewNodeAction"; | ||||
| import {And} from "../../Tags/And"; | ||||
| 
 | ||||
| export default class CreateNewWayAction extends OsmChangeAction { | ||||
| export default class CreateNewWayAction extends OsmCreateAction { | ||||
|     public newElementId: string = undefined | ||||
|     public newElementIdNumber: number = undefined; | ||||
|     private readonly coordinates: ({ nodeId?: number, lat: number, lon: number })[]; | ||||
|     private readonly tags: Tag[]; | ||||
|     private readonly _options: { | ||||
|  | @ -55,7 +56,7 @@ export default class CreateNewWayAction extends OsmChangeAction { | |||
| 
 | ||||
| 
 | ||||
|         const id = changes.getNewID() | ||||
| 
 | ||||
|         this.newElementIdNumber  = id | ||||
|         const newWay = <ChangeDescription>{ | ||||
|             id, | ||||
|             type: "way", | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| import OsmChangeAction from "./OsmChangeAction"; | ||||
| import OsmChangeAction, {OsmCreateAction} from "./OsmChangeAction"; | ||||
| import {Tag} from "../../Tags/Tag"; | ||||
| import {Changes} from "../Changes"; | ||||
| import {ChangeDescription} from "./ChangeDescription"; | ||||
|  | @ -31,7 +31,7 @@ interface CoordinateInfo { | |||
| /** | ||||
|  * More or less the same as 'CreateNewWay', except that it'll try to reuse already existing points | ||||
|  */ | ||||
| export default class CreateWayWithPointReuseAction extends OsmChangeAction { | ||||
| export default class CreateWayWithPointReuseAction extends OsmCreateAction { | ||||
|     private readonly _tags: Tag[]; | ||||
|     /** | ||||
|      * lngLat-coordinates | ||||
|  | @ -40,6 +40,9 @@ export default class CreateWayWithPointReuseAction extends OsmChangeAction { | |||
|     private _coordinateInfo: CoordinateInfo[]; | ||||
|     private _state: FeaturePipelineState; | ||||
|     private _config: MergePointConfig[]; | ||||
|      | ||||
|     public newElementId: string = undefined; | ||||
|     public newElementIdNumber: number = undefined | ||||
| 
 | ||||
|     constructor(tags: Tag[], | ||||
|                 coordinates: [number, number][], | ||||
|  | @ -87,7 +90,8 @@ export default class CreateWayWithPointReuseAction extends OsmChangeAction { | |||
|                     properties: { | ||||
|                         "move": "yes", | ||||
|                         "osm-id": reusedPoint.node.properties.id, | ||||
|                         "id": "new-geometry-move-existing" + i | ||||
|                         "id": "new-geometry-move-existing" + i, | ||||
|                         "distance":GeoOperations.distanceBetween(coordinateInfo.lngLat, reusedPoint.node.geometry.coordinates) | ||||
|                     }, | ||||
|                     geometry: { | ||||
|                         type: "LineString", | ||||
|  | @ -97,8 +101,23 @@ export default class CreateWayWithPointReuseAction extends OsmChangeAction { | |||
|                 features.push(moveDescription) | ||||
| 
 | ||||
|             } else { | ||||
|                 // The geometry is moved
 | ||||
|                 // The geometry is moved, the point is reused
 | ||||
|                 geometryMoved = true | ||||
| 
 | ||||
|                 const reuseDescription = { | ||||
|                     type: "Feature", | ||||
|                     properties: { | ||||
|                         "move": "no", | ||||
|                         "osm-id": reusedPoint.node.properties.id, | ||||
|                         "id": "new-geometry-reuse-existing" + i, | ||||
|                         "distance":GeoOperations.distanceBetween(coordinateInfo.lngLat, reusedPoint.node.geometry.coordinates) | ||||
|                     }, | ||||
|                     geometry: { | ||||
|                         type: "LineString", | ||||
|                         coordinates: [coordinateInfo.lngLat, reusedPoint.node.geometry.coordinates] | ||||
|                     } | ||||
|                 } | ||||
|                 features.push(reuseDescription) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -138,11 +157,10 @@ export default class CreateWayWithPointReuseAction extends OsmChangeAction { | |||
|             features.push(newGeometry) | ||||
| 
 | ||||
|         } | ||||
|         console.log("Preview:", features) | ||||
|         return new StaticFeatureSource(features, false) | ||||
|     } | ||||
| 
 | ||||
|     protected async CreateChangeDescriptions(changes: Changes): Promise<ChangeDescription[]> { | ||||
|     public async CreateChangeDescriptions(changes: Changes): Promise<ChangeDescription[]> { | ||||
|         const theme = this._state.layoutToUse.id | ||||
|         const allChanges: ChangeDescription[] = [] | ||||
|         const nodeIdsToUse: { lat: number, lon: number, nodeId?: number }[] = [] | ||||
|  | @ -196,6 +214,8 @@ export default class CreateWayWithPointReuseAction extends OsmChangeAction { | |||
|         }) | ||||
|          | ||||
|         allChanges.push(...(await newWay.CreateChangeDescriptions(changes))) | ||||
|         this.newElementId = newWay.newElementId | ||||
|         this.newElementIdNumber = newWay.newElementIdNumber | ||||
|         return allChanges | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ export default abstract class OsmChangeAction { | |||
|     public readonly trackStatistics: boolean; | ||||
|     /** | ||||
|      * The ID of the object that is the center of this change. | ||||
|      * Null if the action creates a new object | ||||
|      * Null if the action creates a new object (at initialization) | ||||
|      * Undefined if such an id does not make sense | ||||
|      */ | ||||
|     public readonly mainObjectId: string; | ||||
|  | @ -30,4 +30,11 @@ export default abstract class OsmChangeAction { | |||
|     } | ||||
| 
 | ||||
|     protected abstract CreateChangeDescriptions(changes: Changes): Promise<ChangeDescription[]> | ||||
| } | ||||
| } | ||||
| 
 | ||||
| export abstract class OsmCreateAction extends OsmChangeAction{ | ||||
| 
 | ||||
|     public newElementId : string | ||||
|     public newElementIdNumber: number | ||||
|      | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue