def get_affected(request, objType, objIds): t = p.GetTransaction("ACCESS SHARE") osmData = pgmap.OsmData() t.GetObjectsById(objType, list(map(int, objIds.split(","))), osmData) affectedData = pgmap.OsmData() t.GetAffectedObjects(osmData, affectedData) sio = io.BytesIO() enc = pgmap.PyOsmXmlEncode(sio, common.xmlAttribs) affectedData.StreamTo(enc) return HttpResponse(sio.getvalue(), content_type='text/xml')
def ways_for_node(request, objType, objId): t = p.GetTransaction("ACCESS SHARE") #Check reference object exists osmData = pgmap.OsmData() t.GetObjectsById(objType, pgmap.seti64([int(objId)]), osmData) # From the 0.6 spec: "There is no error if the element does not exist." osmData = pgmap.OsmData() t.GetWaysForNodes([int(objId)], osmData) sio = io.BytesIO() enc = pgmap.PyOsmXmlEncode(sio, common.xmlAttribs) osmData.StreamTo(enc) return HttpResponse(sio.getvalue(), content_type='text/xml')
def modify_way(wayIn, refsIn, tagsIn, user, timestamp = None): way = pgmap.OsmWay() way.objId = wayIn.objId way.metaData.version = wayIn.metaData.version + 1 if timestamp is None: way.metaData.timestamp = int(time.time()) else: way.metaData.timestamp = int(timestamp) way.metaData.changeset = 1000 way.metaData.uid = user.id way.metaData.username = user.username way.metaData.visible = True for k in tagsIn: way.tags[k] = tagsIn[k] for ref in refsIn: way.refs.append(ref) data = pgmap.OsmData() data.ways.append(way) createdNodeIds = pgmap.mapi64i64() createdWayIds = pgmap.mapi64i64() createdRelationIds = pgmap.mapi64i64() errStr = pgmap.PgMapError() t = p.GetTransaction("EXCLUSIVE") ok = t.StoreObjects(data, createdNodeIds, createdWayIds, createdRelationIds, False, errStr) if not ok: t.Abort() print (errStr.errStr) else: t.Commit() return ok, way
def create_relation(uid, username, refs, changeset=1000): relation = pgmap.OsmRelation() relation.objId = -1 relation.metaData.version = 1 relation.metaData.timestamp = 0 relation.metaData.changeset = changeset relation.metaData.uid = uid relation.metaData.username = username relation.metaData.visible = True relation.tags["test"] = "moon" for refTypeStr, refId, refRole in refs: relation.refTypeStrs.append(refTypeStr) relation.refIds.append(refId) relation.refRoles.append(refRole) data = pgmap.OsmData() data.relations.append(relation) createdNodeIds = pgmap.mapi64i64() createdWayIds = pgmap.mapi64i64() createdRelationIds = pgmap.mapi64i64() errStr = pgmap.PgMapError() t = p.GetTransaction("EXCLUSIVE") ok = t.StoreObjects(data, createdNodeIds, createdWayIds, createdRelationIds, False, errStr) if not ok: t.Abort() print(errStr.errStr) return None else: t.Commit() relation.objId = createdRelationIds[-1] return relation
def create_way(uid, username, refs, changeset = 1000, timestamp = None): way = pgmap.OsmWay() way.objId = -1 way.metaData.version = 1 if timestamp is None: way.metaData.timestamp = int(time.time()) else: way.metaData.timestamp = int(timestamp) way.metaData.changeset = changeset way.metaData.uid = uid way.metaData.username = username way.metaData.visible = True way.tags["test"] = "spring" for ref in refs: way.refs.append(ref) data = pgmap.OsmData() data.ways.append(way) createdNodeIds = pgmap.mapi64i64() createdWayIds = pgmap.mapi64i64() createdRelationIds = pgmap.mapi64i64() errStr = pgmap.PgMapError() t = p.GetTransaction("EXCLUSIVE") ok = t.StoreObjects(data, createdNodeIds, createdWayIds, createdRelationIds, False, errStr) if not ok: t.Abort() print (errStr.errStr) return None else: t.Commit() way.objId = createdWayIds[-1] return way
def modify_node(nodeIn, nodeCurrentVer, user, timestamp = None): node = pgmap.OsmNode() node.objId = nodeIn.objId node.metaData.version = nodeCurrentVer + 1 if timestamp is None: node.metaData.timestamp = int(time.time()) else: node.metaData.timestamp = int(timestamp) node.metaData.changeset = 1000 node.metaData.uid = user.id node.metaData.username = user.username node.metaData.visible = True node.tags["test"] = "winter" node.lat = nodeIn.lat + 0.1 node.lon = nodeIn.lon + 0.2 data = pgmap.OsmData() data.nodes.append(node) createdNodeIds = pgmap.mapi64i64() createdWayIds = pgmap.mapi64i64() createdRelationIds = pgmap.mapi64i64() errStr = pgmap.PgMapError() t = p.GetTransaction("EXCLUSIVE") ok = t.StoreObjects(data, createdNodeIds, createdWayIds, createdRelationIds, False, errStr) if not ok: t.Abort() print (errStr.errStr) else: t.Commit() return ok, node
def modify_relation(uid, username, relationIn, refsIn, tagsIn): relation = pgmap.OsmRelation() relation.objId = relationIn.objId relation.metaData.version = relationIn.metaData.version + 1 relation.metaData.timestamp = int(time.time()) relation.metaData.changeset = 1000 relation.metaData.uid = uid relation.metaData.username = username relation.metaData.visible = True for k in tagsIn: relation.tags[k] = tagsIn[k] for refTypeStr, refId, refRole in refsIn: relation.refTypeStrs.append(refTypeStr) relation.refIds.append(refId) relation.refRoles.append(refRole) data = pgmap.OsmData() data.relations.append(relation) createdNodeIds = pgmap.mapi64i64() createdWayIds = pgmap.mapi64i64() createdRelationIds = pgmap.mapi64i64() errStr = pgmap.PgMapError() t = p.GetTransaction("EXCLUSIVE") ok = t.StoreObjects(data, createdNodeIds, createdWayIds, createdRelationIds, False, errStr) if not ok: t.Abort() print (errStr.errStr) return None else: t.Commit() return relation
def getoscdiff(timebase, cat1, cat2, cat3): timenow = int(time.time()) epochts = int(time.mktime(settings.REPLICATE_EPOCH.timetuple())) if timebase == "minute": pageStep = 60000000 if timebase == "hour": pageStep = 60000000 * 60 if timebase == "day": pageStep = 60000000 * 60 * 24 pageStep2 = pageStep / 1000 pageStep3 = pageStep2 / 1000 pageStartTimestamp = int(cat1) * pageStep + int(cat2) * pageStep2 + int( cat3) * pageStep3 + epochts elapsedInPage = timenow - pageStartTimestamp if elapsedInPage < 0: return HttpResponseNotFound("Page does not exist") t = p.GetTransaction("ACCESS SHARE") osmData = pgmap.OsmData() t.GetReplicateDiff(pageStartTimestamp - pageStep3, pageStartTimestamp, osmData) sio = io.BytesIO() enc = pgmap.PyOsmXmlEncode(sio, common.xmlAttribs) osmData.StreamTo(enc) return sio.getvalue()
def relations_for_obj(request, objType, objId): t = p.GetTransaction("ACCESS SHARE") osmData = pgmap.OsmData() t.GetRelationsForObjs(objType.encode("UTF-8"), [int(objId)], osmData) sio = io.BytesIO() enc = pgmap.PyOsmXmlEncode(sio, common.xmlAttribs) osmData.StreamTo(enc) return HttpResponse(sio.getvalue(), content_type='text/xml')
def object_history(request, objType, objId): t = p.GetTransaction("ACCESS SHARE") osmData = pgmap.OsmData() t.GetObjectsHistoryById(objType, [int(objId)], osmData) sio = io.BytesIO() enc = pgmap.PyOsmXmlEncode(sio, common.xmlAttribs) osmData.StreamTo(enc) return HttpResponse(sio.getvalue(), content_type='text/xml')
def ways_for_node(request, objType, objId): t = p.GetTransaction("ACCESS SHARE") osmData = pgmap.OsmData() t.GetWaysForNodes([int(objId)], osmData) sio = io.BytesIO() enc = pgmap.PyOsmXmlEncode(sio, common.xmlAttribs) osmData.StreamTo(enc) return HttpResponse(sio.getvalue(), content_type='text/xml')
def DecodeOsmdataResponse(xml): data = pgmap.OsmData() dec = pgmap.OsmXmlDecodeString() dec.output = data for chunk in xml: chunkDec = chunk.decode('utf-8') dec.DecodeSubString(chunkDec, len(chunkDec), False) dec.DecodeSubString("", 0, True) return data
def get_affected_from_upload(request): t = p.GetTransaction("ACCESS SHARE") affectedData = pgmap.OsmData() t.GetAffectedObjects(request.data, affectedData) sio = io.BytesIO() enc = pgmap.PyOsmXmlEncode(sio) affectedData.StreamTo(enc) return HttpResponse(sio.getvalue(), content_type='text/xml')
def object_version(request, objType, objId, objVer): t = p.GetTransaction("ACCESS SHARE") osmData = pgmap.OsmData() idVerPair = pgmap.pairi64i64(int(objId), int(objVer)) t.GetObjectsByIdVer(objType, [idVerPair], osmData) sio = io.BytesIO() enc = pgmap.PyOsmXmlEncode(sio, common.xmlAttribs) osmData.StreamTo(enc) return HttpResponse(sio.getvalue(), content_type='text/xml')
def object_history(request, objType, objId): t = p.GetTransaction("ACCESS SHARE") osmData = pgmap.OsmData() t.GetObjectsHistoryById(objType, [int(objId)], osmData) if len(osmData.nodes) + len(osmData.ways) + len(osmData.relations) == 0: return HttpResponseNotFound("{} {} not found".format(objType, objId)) sio = io.BytesIO() enc = pgmap.PyOsmXmlEncode(sio, common.xmlAttribs) osmData.StreamTo(enc) return HttpResponse(sio.getvalue(), content_type='text/xml')
def delete_object(objIn, user, tIn=None, timestamp=None): if isinstance(objIn, pgmap.OsmNode): obj = pgmap.OsmNode() elif isinstance(objIn, pgmap.OsmWay): obj = pgmap.OsmWay() elif isinstance(objIn, pgmap.OsmRelation): obj = pgmap.OsmRelation() obj.objId = objIn.objId obj.metaData.version = objIn.metaData.version + 1 if timestamp is None: obj.metaData.timestamp = int(time.time()) else: obj.metaData.timestamp = int(timestamp) obj.metaData.changeset = 1000 obj.metaData.uid = user.id obj.metaData.username = user.username obj.metaData.visible = False if isinstance(objIn, pgmap.OsmNode): obj.lat = objIn.lat obj.lon = objIn.lon data = pgmap.OsmData() if isinstance(objIn, pgmap.OsmNode): data.nodes.append(obj) elif isinstance(objIn, pgmap.OsmWay): data.ways.append(obj) elif isinstance(objIn, pgmap.OsmRelation): data.relations.append(obj) createdNodeIds = pgmap.mapi64i64() createdWayIds = pgmap.mapi64i64() createdRelationIds = pgmap.mapi64i64() errStr = pgmap.PgMapError() if tIn is not None: t = tIn else: t = p.GetTransaction("EXCLUSIVE") ok = t.StoreObjects(data, createdNodeIds, createdWayIds, createdRelationIds, False, errStr) if tIn is None: if not ok: t.Abort() print(errStr.errStr) else: t.Commit() return ok
def parse(self, stream, media_type, parser_context): data = pgmap.OsmData() dec = pgmap.OsmXmlDecodeString() dec.output = data pageSize = 100000 while True: inputXml = stream.read(pageSize) if len(inputXml) == 0: break dec.DecodeSubString(inputXml.decode("UTF-8"), len(inputXml), False) dec.DecodeSubString("", 0, True) if not dec.parseCompletedOk: raise ParseError(detail=dec.errString) return data
def index(request, objType): if objType not in request.GET: return HttpResponseBadRequest("Incorrect arguments in URL") try: objIds = map(int, request.GET[objType].split(",")) except ValueError as err: return HttpResponseBadRequest(err) t = p.GetTransaction("ACCESS SHARE") osmData = pgmap.OsmData() t.GetObjectsById(objType[:-1], list(objIds), osmData) sio = io.BytesIO() enc = pgmap.PyOsmXmlEncode(sio, common.xmlAttribs) osmData.StreamTo(enc) return HttpResponse(sio.getvalue(), content_type='text/xml')
def create_node(uid, username, nearbyNode=None, changeset=1000, timestamp=None): node = pgmap.OsmNode() node.objId = -1 node.metaData.version = 1 if timestamp is None: node.metaData.timestamp = int(time.time()) else: node.metaData.timestamp = int(timestamp) node.metaData.changeset = changeset node.metaData.uid = uid node.metaData.username = username node.metaData.visible = True node.tags["test"] = "autumn" if nearbyNode is None: node.lat = 43.0 + random.uniform(-1.0, 1.0) node.lon = -70.3 + random.uniform(-1.0, 1.0) else: node.lat = nearbyNode.lat + random.uniform(-0.00015, 0.00015) node.lon = nearbyNode.lon + random.uniform(-0.00015, 0.00015) data = pgmap.OsmData() data.nodes.append(node) createdNodeIds = pgmap.mapi64i64() createdWayIds = pgmap.mapi64i64() createdRelationIds = pgmap.mapi64i64() errStr = pgmap.PgMapError() t = p.GetTransaction("EXCLUSIVE") ok = t.StoreObjects(data, createdNodeIds, createdWayIds, createdRelationIds, False, errStr) if not ok: t.Abort() print(errStr.errStr) return None else: t.Commit() node.objId = createdNodeIds[-1] return node
def test_delete_static_relation(self): #Find a relation that is not part of any other relation anonClient = Client() response = anonClient.get( reverse('querymap:querymap') + "?bbox={},{},{},{}".format(*self.roi)) self.assertEqual(response.status_code, 200) data = DecodeOsmdataResponse(response.streaming_content) nodeIdSet, wayIdSet, relationIdSet, nodeMems, wayMems, relationMems = self.find_object_ids( data) candidateIds = list(relationIdSet.difference(relationMems)) t = p.GetTransaction("EXCLUSIVE") #Try to find a suitable candidate for deletion for candidateId in candidateIds: #Use first object among candidates idDicts = GetOsmDataIndex(data) nodeIdDict, wayIdDict, relationIdDict = idDicts['node'], idDicts[ 'way'], idDicts['relation'] relationObjToDel = relationIdDict[candidateId] #Check for parents of relation, skip if found parentData = pgmap.OsmData() t.GetRelationsForObjs("relation", [int(candidateId)], parentData) if len(parentData.relations) > 0: continue ok = delete_object(relationObjToDel, self.user, t) if not ok: t.Abort() self.assertEqual(ok, True) t.Commit() self.check_relation_in_query(relationObjToDel, self.roi, False) return #Success! t.Commit() print( "No free relations (with no parent relations) in ROI for testing")
def GetObj(p, objType, objId): t = p.GetTransaction("ACCESS SHARE") osmData = pgmap.OsmData() #Watch out, this goes out of scope! t.GetObjectsById(objType, [objId], osmData) del t objs = None if objType == "node": objs = osmData.nodes if len(objs) == 0: return None return pgmap.OsmNode(objs[0]) if objType == "way": objs = osmData.ways if len(objs) == 0: return None return pgmap.OsmWay(objs[0]) if objType == "relation": objs = osmData.relations if len(objs) == 0: return None return pgmap.OsmRelation(objs[0]) return None
def full_obj(request, objType, objId): t = p.GetTransaction("ACCESS SHARE") osmData = pgmap.OsmData() t.GetFullObjectById(objType, int(objId), osmData) if len(osmData.nodes) + len(osmData.ways) + len(osmData.relations) == 0: # No live version found. Check to see if this ever existed. t.GetObjectsHistoryById(objType, [int(objId)], osmData) if len(osmData.nodes) + len(osmData.ways) + len( osmData.relations) == 0: return HttpResponseNotFound("{} {} not found".format( objType, objId)) else: # The object once existed, therefore it was deleted. return HttpResponse("Gone", status=410, content_type="text/plain") sio = io.BytesIO() enc = pgmap.PyOsmXmlEncode(sio, common.xmlAttribs) osmData.StreamTo(enc) return HttpResponse(sio.getvalue(), content_type='text/xml')
def element(request, objType, objId): if request.method == 'GET': osmData = pgmap.OsmData() t = p.GetTransaction("ACCESS SHARE") t.GetObjectsById(objType.encode("UTF-8"), pgmap.seti64([int(objId)]), osmData) if len(osmData.nodes) + len(osmData.ways) + len( osmData.relations) == 0: return HttpResponseNotFound("{} {} not found".format( objType, objId)) sio = io.BytesIO() enc = pgmap.PyOsmXmlEncode(sio, common.xmlAttribs) osmData.StreamTo(enc) return HttpResponse(sio.getvalue(), content_type='text/xml') if request.method in ['PUT', 'DELETE']: t = p.GetTransaction("EXCLUSIVE") action = None if request.method == "PUT": action = "modify" if request.method == "DELETE": action = "delete" obj = None if objType == "node": obj = request.data.nodes[0] if objType == "way": obj = request.data.ways[0] if objType == "relation": obj = request.data.relations[0] if obj.objId != objId: return HttpResponseBadRequest("Object has wrong ID") ret = upload_single_object(action, request, obj, objType, t) if ret != True: return ret return HttpResponse("", content_type='text/plain')
settings["dbname"], settings["dbuser"], settings["dbpass"], settings["dbhost"]), settings["dbtableprefix"], settings["dbtabletestprefix"]) print("Connected to database", p.Ready()) t = p.GetTransaction(b"ACCESS SHARE") if 0: sio = io.BytesIO() #enc = pgmap.PyO5mEncode(sio) enc = pgmap.PyOsmXmlEncode(sio) print( t.MapQuery((-1.1473846, 50.7360206, -0.9901428, 50.8649113), 0, enc)) data = sio.getvalue() print(len(data), "bytes") if 1: osmData = pgmap.OsmData() objectIds = [1000594005591, 1000595178493, 1000594446551] t.GetObjectsById("node", pgmap.seti64(objectIds), osmData) print(len(osmData.nodes)) for i in range(len(osmData.nodes)): node = osmData.nodes[i] print(type(node)) print(node.objId, node.lat, node.lon) t.Commit()
def upload_block(action, block, changesetId, t, responseRoot, uid, username, timestamp, createdNodeIds, createdWayIds, createdRelationIds, ifunused=False): if action == "create": ret = upload_check_create(block.nodes) if ret is not None: return ret ret = upload_check_create(block.ways) if ret is not None: return ret ret = upload_check_create(block.relations) if ret is not None: return ret for i in range(block.nodes.size()): block.nodes[i].metaData.version = 1 for i in range(block.ways.size()): block.ways[i].metaData.version = 1 for i in range(block.relations.size()): block.relations[i].metaData.version = 1 elif action in ["modify", "delete"]: ret = upload_check_modify(block.nodes) if ret is not None: return ret ret = upload_check_modify(block.ways) if ret is not None: return ret ret = upload_check_modify(block.relations) if ret is not None: return ret #Increment version numbers for modified objects for i in range(block.nodes.size()): block.nodes[i].metaData.version += 1 for i in range(block.ways.size()): block.ways[i].metaData.version += 1 for i in range(block.relations.size()): block.relations[i].metaData.version += 1 else: return True #Skip this block ret = upload_check_way_mems(action, block.ways) if ret is not None: return ret #Check changeset value is consistent for i in range(block.nodes.size()): if block.nodes[i].metaData.changeset != int(changesetId): return HttpResponseBadRequest( "Changeset does not match expected value", content_type="text/plain") for i in range(block.ways.size()): if block.ways[i].metaData.changeset != int(changesetId): return HttpResponseBadRequest( "Changeset does not match expected value", content_type="text/plain") for i in range(block.relations.size()): if block.relations[i].metaData.changeset != int(changesetId): return HttpResponseBadRequest( "Changeset does not match expected value", content_type="text/plain") #Get list of modified objects, check they are unique modNodeIdSet, modWayIdSet, modRelationIdSet = set(), set(), set() for i in range(block.nodes.size()): node = block.nodes[i] if node.objId in modNodeIdSet: return HttpResponseBadRequest("Modified object ID is not unique", content_type="text/plain") modNodeIdSet.add(node.objId) for i in range(block.ways.size()): way = block.ways[i] if way.objId in modWayIdSet: return HttpResponseBadRequest("Modified object ID is not unique", content_type="text/plain") modWayIdSet.add(way.objId) for i in range(block.relations.size()): relation = block.relations[i] if relation.objId in modRelationIdSet: return HttpResponseBadRequest("Modified object ID is not unique", content_type="text/plain") modRelationIdSet.add(relation.objId) #Get list of referenced objects refedNodes, refedWays, refedRelations = set(), set(), set() for i in range(block.nodes.size()): node = block.nodes[i] refedNodes.add(node.objId) for i in range(block.ways.size()): way = block.ways[i] refedWays.add(way.objId) for ref in way.refs: refedNodes.add(ref) for i in range(block.relations.size()): relation = block.relations[i] refedRelations.add(relation.objId) for i, refId in enumerate(relation.refIds): refTypeStr = relation.refTypeStrs[i] if refTypeStr == "node": refedNodes.add(refId) if refTypeStr == "way": refedWays.add(refId) if refTypeStr == "relation": refedRelations.add(refId) #Check referenced positive ID objects already exist (to ensure #non existent nodes or ways are not added to ways or relations). posRefedNodes = [objId for objId in refedNodes if objId > 0] posRefedWays = [objId for objId in refedWays if objId > 0] posRefedRelations = [objId for objId in refedRelations if objId > 0] foundNodeData = pgmap.OsmData() t.GetObjectsById("node", posRefedNodes, foundNodeData) foundNodeIndex = GetOsmDataIndex(foundNodeData)["node"] if set(posRefedNodes) != set(foundNodeIndex.keys()): return HttpResponseNotFound("Referenced node(s) not found") foundWayData = pgmap.OsmData() t.GetObjectsById("way", posRefedWays, foundWayData) foundWayIndex = GetOsmDataIndex(foundWayData)["way"] if set(posRefedWays) != set(foundWayIndex.keys()): return HttpResponseNotFound("Referenced way(s) not found") foundRelationData = pgmap.OsmData() t.GetObjectsById("relation", posRefedRelations, foundRelationData) foundRelationIndex = GetOsmDataIndex(foundRelationData)["relation"] if set(posRefedRelations) != set(foundRelationIndex.keys()): return HttpResponseNotFound("Referenced relation(s) not found") #Check versions of updated/deleted objects match what we expect dataIndex = GetOsmDataIndex(block) nodeObjsById, wayObjsById, relationObjsById = dataIndex['node'], dataIndex[ 'way'], dataIndex['relation'] for objId in nodeObjsById: if nodeObjsById[objId].metaData.version > 1 and nodeObjsById[ objId].metaData.version != foundNodeIndex[ objId].metaData.version + 1: return HttpResponse("Node has wrong version", status=409, content_type="text/plain") for objId in wayObjsById: if wayObjsById[objId].metaData.version > 1 and wayObjsById[ objId].metaData.version != foundWayIndex[ objId].metaData.version + 1: return HttpResponse("Way has wrong version", status=409, content_type="text/plain") for objId in relationObjsById: if relationObjsById[objId].metaData.version > 1 and relationObjsById[ objId].metaData.version != foundRelationIndex[ objId].metaData.version + 1: return HttpResponse("Relation has wrong version", status=409, content_type="text/plain") if action == "delete": #Check that deleting objects doesn't break anything parentRelationsForRelations = pgmap.OsmData() t.GetRelationsForObjs("relation", list(relationObjsById.keys()), parentRelationsForRelations) parentRelationsForRelationsIndex = GetOsmDataIndex( parentRelationsForRelations)["relation"] referencedChildren = {} for parentId in parentRelationsForRelationsIndex: if parentId in relationObjsById.keys(): continue #This object is being deleted anyway parent = parentRelationsForRelationsIndex[parentId] for refTypeStr, refId in zip(parent.refTypeStrs, parent.refIds): if refTypeStr != "relation": continue if refId in relationObjsById.keys(): referencedChildren[refId] = parent.objId if len(referencedChildren) > 0: if not ifunused: k, v = GetAnyKeyValue(referencedChildren) err = "The relation #{} is used in relation #{}.".format(k, v) return HttpResponse(err, status=412, content_type="text/plain") else: filtered = pgmap.OsmData() for i in range(len(block.relations)): relation = block.relations[i] if relation.objId in referencedChildren: continue filtered.relations.append(relation) block.relations = filtered.relations relationsObjsById = GetOsmDataIndex(block)['relation'] parentRelationsForWays = pgmap.OsmData() t.GetRelationsForObjs("way", list(wayObjsById.keys()), parentRelationsForWays) parentRelationsForWaysIndex = GetOsmDataIndex( parentRelationsForWays)["relation"] referencedChildren = {} for parentId in parentRelationsForWaysIndex: if parentId in relationObjsById.keys(): continue #This object is being deleted anyway parent = parentRelationsForWaysIndex[parentId] for refTypeStr, refId in zip(parent.refTypeStrs, parent.refIds): if refTypeStr != "way": continue if refId in wayObjsById.keys(): referencedChildren[refId] = parent.objId if len(referencedChildren) > 0: if not ifunused: k, v = GetAnyKeyValue(referencedChildren) err = "Way #{} still used by relation #{}.".format(k, v) return HttpResponse(err, status=412, content_type="text/plain") else: filtered = pgmap.OsmData() for i in range(len(block.ways)): way = block.ways[i] if way.objId in referencedChildren: continue filtered.ways.append(way) block.ways = filtered.ways wayObjsById = GetOsmDataIndex(block)['way'] parentWayForNodes = pgmap.OsmData() t.GetWaysForNodes(list(nodeObjsById.keys()), parentWayForNodes) parentWayForNodesIndex = GetOsmDataIndex(parentWayForNodes)["way"] referencedChildren = {} for parentId in parentWayForNodesIndex: if parentId in wayObjsById.keys(): continue #This object is being deleted anyway parent = parentWayForNodesIndex[parentId] for ref in parent.refs: if ref in nodeObjsById.keys(): referencedChildren[ref] = parent.objId if len(referencedChildren) > 0: if not ifunused: k, v = GetAnyKeyValue(referencedChildren) err = "#{} is still used by way #{}.".format(k, v) return HttpResponse(err, status=412, content_type="text/plain") else: filtered = pgmap.OsmData() for i in range(len(block.nodes)): node = block.nodes[i] if node.objId in referencedChildren: continue filtered.nodes.append(node) block.nodes = filtered.nodes nodeObjsById = GetOsmDataIndex(block)['node'] parentRelationsForNodes = pgmap.OsmData() t.GetRelationsForObjs("node", list(nodeObjsById.keys()), parentRelationsForNodes) parentRelationsForNodesIndex = GetOsmDataIndex( parentRelationsForNodes)["relation"] referencedChildren = {} for parentId in parentRelationsForNodesIndex: parent = parentRelationsForNodesIndex[parentId] for refTypeStr, refId in zip(parent.refTypeStrs, parent.refIds): if refTypeStr != "node": continue if refId in nodeObjsById.keys(): referencedChildren[refId] = parent.objId if len(referencedChildren) > 0: if not ifunused: k, v = GetAnyKeyValue(referencedChildren) err = "Node #{} is still used by relation #{}.".format(k, v) return HttpResponse(err, status=412, content_type="text/plain") else: filtered = pgmap.OsmData() for i in range(len(block.nodes)): node = block.nodes[i] if node.objId in referencedChildren: continue filtered.nodes.append(node) block.nodes = filtered.nodes nodeObjsById = GetOsmDataIndex(block)['node'] #Get complete set of query objects based on modified objects #TODO if action in ["modify", "delete"]: #Get complete set of query objects for original data existingAffectedObjects = pgmap.OsmData() t.GetAffectedObjects(block, existingAffectedObjects) #Set visiblity flag visible = action != "delete" for i in range(block.nodes.size()): block.nodes[i].metaData.visible = visible for i in range(block.ways.size()): block.ways[i].metaData.visible = visible for i in range(block.relations.size()): block.relations[i].metaData.visible = visible #Set user info for i in range(block.nodes.size()): block.nodes[i].metaData.uid = uid block.nodes[i].metaData.username = username block.nodes[i].metaData.timestamp = int(timestamp) for i in range(block.ways.size()): block.ways[i].metaData.uid = uid block.ways[i].metaData.username = username block.ways[i].metaData.timestamp = int(timestamp) for i in range(block.relations.size()): block.relations[i].metaData.uid = uid block.relations[i].metaData.username = username block.relations[i].metaData.timestamp = int(timestamp) errStr = pgmap.PgMapError() ok = t.StoreObjects(block, createdNodeIds, createdWayIds, createdRelationIds, False, errStr) if not ok: return HttpResponseServerError(errStr.errStr, content_type='text/plain') #Update diff result upload_update_diff_result(action, "node", block.nodes, createdNodeIds, responseRoot) upload_update_diff_result(action, "way", block.ways, createdWayIds, responseRoot) upload_update_diff_result(action, "relation", block.relations, createdRelationIds, responseRoot) #Update changeset bbox based on edits #TODO return True