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 test_expand_bbox(self): cs = CreateTestChangeset(self.user) response = self.client.post(reverse('changeset:expand_bbox', args=(cs.objId, )), self.expandBboxXml, content_type='text/xml') self.assertEqual(response.status_code, 200) t = p.GetTransaction("ACCESS SHARE") cs2 = pgmap.PgChangeset() errStr = pgmap.PgMapError() t.GetChangeset(cs.objId, cs2, errStr) self.assertEqual(cs2.bbox_set, True) self.assertEqual(abs(cs2.y1 - 50.2964626834) < 1e-5, True) self.assertEqual(abs(cs2.y2 - 51.7985258134) < 1e-5, True) self.assertEqual(abs(cs2.x1 + 5.24880409375) < 1e-5, True) self.assertEqual(abs(cs2.x2 + 3.08999061719) < 1e-5, True) xml = fromstring(response.content) self.assertEqual(xml.tag, "osm") csout = xml.find("changeset") self.assertEqual(int(csout.attrib["id"]) == cs.objId, True) self.assertEqual( abs(float(csout.attrib["min_lat"]) - 50.2964626834) < 1e-5, True) self.assertEqual( abs(float(csout.attrib["max_lat"]) - 51.7985258134) < 1e-5, True) self.assertEqual( abs(float(csout.attrib["min_lon"]) + 5.24880409375) < 1e-5, True) self.assertEqual( abs(float(csout.attrib["max_lon"]) + 3.08999061719) < 1e-5, True) t.Commit()
def list_changesets(request): bbox = request.GET.get('bbox', None) #min_lon,min_lat,max_lon,max_lat user_uid = int(request.GET.get('user', 0)) display_name = request.GET.get('display_name', None) timearg = request.GET.get('time', None) openarg = request.GET.get('open', None) close = request.GET.get('closed', None) changesetsToGet = request.GET.get('changesets', None) #Check display_name or uid actually exists if display_name is not None: try: user = User.objects.get(username=display_name) user_uid = user.id except ObjectDoesNotExist: try: user = LegacyAccount.objects.get(username=display_name) user_uid = user.uid except ObjectDoesNotExist: return HttpResponseNotFound("User not found") changesets = pgmap.vectorchangeset() errStr = pgmap.PgMapError() t = p.GetTransaction("ACCESS SHARE") ok = t.GetChangesets(changesets, int(user_uid), errStr) t.Commit() changesetLi = [] for i in range(len(changesets)): changesetLi.append(changesets[i]) return SerializeChangesets(changesetLi)
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 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(request): userRecord = request.user changeset = pgmap.PgChangeset() errStr = pgmap.PgMapError() unicodeTags = {} csIn = request.data.find("changeset") for tag in csIn.findall("tag"): unicodeTags[tag.attrib["k"]] = tag.attrib["v"] if not CheckTags(unicodeTags): return HttpResponseBadRequest("Invalid tags") for tag in unicodeTags: changeset.tags[tag] = unicodeTags[tag] changeset.uid = request.user.id changeset.username = request.user.username t = p.GetTransaction("EXCLUSIVE") changeset.open_timestamp = int(time.time()) cid = t.CreateChangeset(changeset, errStr) if cid == 0: t.Abort() return HttpResponseServerError(errStr.errStr) t.Commit() return HttpResponse(cid, content_type='text/plain')
def test_close_changeset_double_close(self): cs = CreateTestChangeset(self.user) response = self.client.put( reverse('changeset:close', args=(cs.objId, ))) self.assertEqual(response.status_code, 200) t = p.GetTransaction("ACCESS SHARE") cs2 = pgmap.PgChangeset() errStr = pgmap.PgMapError() ret = t.GetChangeset(cs.objId, cs2, errStr) t.Commit() self.assertEqual(cs2.is_open, False) response = self.client.put( reverse('changeset:close', args=(cs.objId, ))) self.assertEqual(response.status_code, 409) self.assertEqual( response.content.decode("UTF-8"), "The changeset {} was closed at {}.".format( cs2.objId, datetime.datetime.fromtimestamp( cs2.close_timestamp).isoformat()))
def CreateTestChangeset(user, tags=None, is_open=True, bbox=None): if tags is None: tags = {'foo': 'bar'} t = p.GetTransaction("EXCLUSIVE") cs = pgmap.PgChangeset() errStr = pgmap.PgMapError() for k in tags: cs.tags[k] = tags[k] cs.username = user.username cs.uid = user.id cs.is_open = is_open cs.open_timestamp = int(time.time()) if not is_open: cs.close_timestamp = int(time.time()) if bbox is not None: cs.bbox_set = True cs.x1 = bbox[0] cs.y1 = bbox[1] cs.x2 = bbox[2] cs.y2 = bbox[3] cid = t.CreateChangeset(cs, errStr) cs.objId = cid t.Commit() del t return cs
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 close(request, changesetId): t = p.GetTransaction("EXCLUSIVE") changesetData = pgmap.PgChangeset() errStr = pgmap.PgMapError() ret = t.GetChangeset(int(changesetId), changesetData, errStr) if ret == -1: return HttpResponseNotFound("Changeset not found") if ret == 0: return HttpResponseServerError(errStr.errStr) if not changesetData.is_open: err = "The changeset {} was closed at {}.".format( changesetData.objId, datetime.datetime.fromtimestamp( changesetData.close_timestamp).isoformat()) response = HttpResponse(err, content_type="text/plain") response.status_code = 409 return response if request.user.id != changesetData.uid: return HttpResponse("This changeset belongs to a different user", status=409, content_type="text/plain") t.CloseChangeset(int(changesetId), int(time.time()), errStr) t.Commit() return SerializeChangesets([changesetData])
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 changeset(request, changesetId): include_discussion = request.GET.get('include_discussion', 'false') == "true" if request.method == 'GET': t = p.GetTransaction("ACCESS SHARE") else: t = p.GetTransaction("EXCLUSIVE") changesetData = pgmap.PgChangeset() errStr = pgmap.PgMapError() ret = t.GetChangeset(int(changesetId), changesetData, errStr) if ret == -1: return HttpResponseNotFound("Changeset not found") if ret == 0: return HttpResponseServerError(errStr.errStr) if request.method == 'GET': t.Commit() return SerializeChangesets([changesetData], include_discussion) if request.method == 'PUT': if request.user.id != changesetData.uid: return HttpResponse("This changeset belongs to a different user", status=409, content_type="text/plain") if not changesetData.is_open: err = "The changeset {} was closed at {}.".format( changesetData.objId, datetime.datetime.fromtimestamp( changesetData.close_timestamp).isoformat()) response = HttpResponse(err, content_type="text/plain") response.status_code = 409 return response unicodeTags = {} csIn = request.data.find("changeset") for tag in csIn.findall("tag"): unicodeTags[tag.attrib["k"]] = tag.attrib["v"] if not CheckTags(unicodeTags): return HttpResponseBadRequest("Invalid tags") changesetData.tags = pgmap.mapstringstring() for tag in unicodeTags: changesetData.tags[tag] = unicodeTags[tag] ok = t.UpdateChangeset(changesetData, errStr) if not ok: t.Abort() return HttpResponseServerError(errStr.errStr) t.Commit() return SerializeChangesets([changesetData])
def handle(self, *args, **options): t = p.GetTransaction("ACCESS SHARE") errStr = pgmap.PgMapError() value = t.GetMetaValue(options['key'][0].encode('utf-8'), errStr) t.Commit() self.stdout.write(self.style.SUCCESS('All done! ' + value))
def upload(request, changesetId): #Check changeset is open and for this user t = p.GetTransaction("EXCLUSIVE") changesetData = pgmap.PgChangeset() errStr = pgmap.PgMapError() ret = t.GetChangeset(int(changesetId), changesetData, errStr) if ret == -1: return HttpResponseNotFound("Changeset not found") if ret == 0: return HttpResponseServerError(errStr.errStr) if not changesetData.is_open: err = "The changeset {} was closed at {}.".format( changesetData.id, changesetData.close_datetime.isoformat()) response = HttpResponse(err, content_type="text/plain") response.status_code = 409 return response if request.user.id != changesetData.uid: return HttpResponse("This changeset belongs to a different user", status=409, content_type="text/plain") #Prepare diff result xml responseRoot = ET.Element('diffResult') doc = ET.ElementTree(responseRoot) responseRoot.attrib["version"] = str(settings.API_VERSION) responseRoot.attrib["generator"] = settings.GENERATOR createdNodeIds = pgmap.mapi64i64() createdWayIds = pgmap.mapi64i64() createdRelationIds = pgmap.mapi64i64() for i in range(request.data.blocks.size()): action = request.data.actions[i] block = request.data.blocks[i] ifunused = request.data.ifunused[i] timestamp = time.time() ret = upload_block(action, block, changesetId, t, responseRoot, request.user.id, request.user.username, timestamp, createdNodeIds, createdWayIds, createdRelationIds, ifunused) if ret != True: print(ret) return ret t.Commit() sio = io.BytesIO() doc.write( sio, str("UTF-8")) # str work around https://bugs.python.org/issue15811 return HttpResponse(sio.getvalue(), content_type='text/xml')
def changeset(request, changesetId): t = p.GetTransaction("ACCESS SHARE") changeset = pgmap.PgChangeset() errStr = pgmap.PgMapError() ok = t.GetChangeset(int(changesetId), changeset, errStr) t.Commit() return render(request, 'objectinfo/changeset.html', {'changeset': changeset})
def tearDown(self): u = User.objects.get(username=self.username) u.delete() errStr = pgmap.PgMapError() t = p.GetTransaction("EXCLUSIVE") ok = t.ResetActiveTables(errStr) if not ok: print(errStr.errStr) t.Commit()
def get_test_changeset(self, cid): t = p.GetTransaction("ACCESS SHARE") cs2 = pgmap.PgChangeset() errStr = pgmap.PgMapError() ret = t.GetChangeset(cid, cs2, errStr) t.Commit() if ret == 0: print(errStr) self.assertEqual(ret != 0, True) if ret == -1: raise KeyError("Changeset not found") return cs2
def handle(self, *args, **options): t = p.GetTransaction("EXCLUSIVE") errStr = pgmap.PgMapError() ok = t.SetMetaValue(options['key'][0].encode('utf-8'), options['value'][0].encode('utf-8'), errStr) if not ok: t.Abort() raise CommandError(errStr.errStr) t.Commit() self.stdout.write(self.style.SUCCESS('All done!'))
def index(request): t = p.GetTransaction("ACCESS SHARE") errStr = pgmap.PgMapError() value = int(t.GetMetaValue("readonly", errStr)) dbStatus = "OK" if value != 0: dbStatus = "Read only" t.Commit() return render(request, 'frontpage/index.html', {'db_status': dbStatus})
def upload_single_object(action, request, obj, objType, t): #Additional validate of input if (request.data.nodes.size() != (objType == "node") or request.data.ways.size() != (objType == "way") or request.data.relations.size() != (objType == "relation")): return HttpResponseBadRequest("Wrong number of objects") changesetId = obj.metaData.changeset #Check changeset is open and for this user changesetData = pgmap.PgChangeset() errStr = pgmap.PgMapError() ret = t.GetChangeset(int(changesetId), changesetData, errStr) if ret == -1: return HttpResponseNotFound("Changeset not found") if ret == 0: return HttpResponseServerError(errStr.errStr) if not changesetData.is_open: err = "The changeset {} was closed at {}.".format( changesetData.id, datetime.datetime.fromtimestamp( changesetData.close_timestamp).isoformat()) response = HttpResponse(err, content_type="text/plain") response.status_code = 409 return response if request.user.id != changesetData.uid: return HttpResponse("This changeset belongs to a different user", status=409, content_type="text/plain") #Prepare diff result xml responseRoot = ET.Element('diffResult') doc = ET.ElementTree(responseRoot) responseRoot.attrib["version"] = str(settings.API_VERSION) responseRoot.attrib["generator"] = settings.GENERATOR createdNodeIds = pgmap.mapi64i64() createdWayIds = pgmap.mapi64i64() createdRelationIds = pgmap.mapi64i64() timestamp = time.time() ret = upload_block("create", request.data, changesetId, t, responseRoot, request.user.id, request.user.username, timestamp, createdNodeIds, createdWayIds, createdRelationIds) if ret != True: return ret t.Commit() return True
def test_close_changeset(self): cs = CreateTestChangeset(self.user) response = self.client.put(reverse('changeset:close', args=(cs.objId,))) self.assertEqual(response.status_code, 200) t = p.GetTransaction("ACCESS SHARE") cs2 = pgmap.PgChangeset() errStr = pgmap.PgMapError() ret = t.GetChangeset(cs.objId, cs2, errStr) t.Commit() self.assertEqual(ret != 0, True) self.assertEqual(cs2.is_open, False)
def handle(self, *args, **options): t = p.GetTransaction("EXCLUSIVE") errStr = pgmap.PgMapError() whereBeforeTimestamp = int(time.time()) - (24 * 60 * 60) closedTimestamp = int(time.time()) value = t.CloseChangesetsOlderThan(whereBeforeTimestamp, closedTimestamp, errStr) t.Commit() self.stdout.write(self.style.SUCCESS('All done!'))
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 expand_bbox(request, changesetId): t = p.GetTransaction("EXCLUSIVE") changesetData = pgmap.PgChangeset() errStr = pgmap.PgMapError() ret = t.GetChangeset(int(changesetId), changesetData, errStr) if ret == -1: return HttpResponseNotFound("Changeset not found") if ret == 0: return HttpResponseServerError(errStr.errStr) if request.user.id != changesetData.uid: return HttpResponse("This changeset belongs to a different user", status=409, content_type="text/plain") if not changesetData.is_open: err = "The changeset {} was closed at {}.".format( changesetData.objId, datetime.datetime.fromtimestamp( changesetData.close_timestamp).isoformat()) response = HttpResponse(err, content_type="text/plain") response.status_code = 409 return response for node in request.data.findall("node"): if not changesetData.bbox_set: changesetData.y1 = float(node.attrib["lat"]) changesetData.y2 = float(node.attrib["lat"]) changesetData.x1 = float(node.attrib["lon"]) changesetData.x2 = float(node.attrib["lon"]) changesetData.bbox_set = True else: if float(node.attrib["lat"]) < changesetData.y1: changesetData.y1 = float(node.attrib["lat"]) if float(node.attrib["lat"]) > changesetData.y2: changesetData.y2 = float(node.attrib["lat"]) if float(node.attrib["lon"]) < changesetData.x1: changesetData.x1 = float(node.attrib["lon"]) if float(node.attrib["lon"]) > changesetData.x2: changesetData.x2 = float(node.attrib["lon"]) ok = t.UpdateChangeset(changesetData, errStr) if not ok: t.Abort() return HttpResponseServerError(errStr.errStr) t.Commit() return SerializeChangesets([changesetData])
def history(request): t = p.GetTransaction("ACCESS SHARE") uid = 0 #Corresponds to null user ID for no filtering changesets = pgmap.vectorchangeset() errStr = pgmap.PgMapError() ok = t.GetChangesets(changesets, uid, errStr) t.Commit() changesetLi = [] for i in range(len(changesets)): changesetLi.append(changesets[i]) return render(request, 'objectinfo/history.html', {'changesets': changesetLi})
def setUp(self): self.username = "******" self.password = "******" self.email = '*****@*****.**' self.user = User.objects.create_user(self.username, self.email, self.password) self.client = Client() self.client.login(username=self.username, password=self.password) self.roi = [-1.0684204,50.8038735,-1.0510826,50.812877] errStr = pgmap.PgMapError() t = p.GetTransaction("EXCLUSIVE") ok = t.ResetActiveTables(errStr) if not ok: t.Abort() print (errStr.errStr) else: t.Commit() self.assertEqual(ok, True)
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 download(request, changesetId): t = p.GetTransaction("ACCESS SHARE") osmChange = pgmap.OsmChange() errStr = pgmap.PgMapError() ret = t.GetChangesetOsmChange(int(changesetId), osmChange, errStr) if ret == -1: return HttpResponseNotFound("Changeset not found") if ret == 0: return HttpResponseServerError(errStr.errStr) t.Commit() #print (changesetData.data.empty()) sio = io.BytesIO() outBufWrapped = pgmap.CPyOutbuf(sio) pgmap.SaveToOsmChangeXml(osmChange, outBufWrapped) return HttpResponse(sio.getvalue(), content_type='text/xml')
def list_changesets(request): bbox = request.GET.get('bbox', None) #min_lon,min_lat,max_lon,max_lat user_uid = int(request.GET.get('user', 0)) display_name = request.GET.get('display_name', None) timearg = request.GET.get('time', None) isOpenOnly = request.GET.get('open', 'false') == 'true' isClosedOnly = request.GET.get('closed', 'false') == 'true' changesetsToGet = request.GET.get('changesets', None) #Check display_name or uid actually exists if display_name is not None: try: user = User.objects.get(username=display_name) user_uid = user.id except ObjectDoesNotExist: try: user = LegacyAccount.objects.get(username=display_name) user_uid = user.uid except ObjectDoesNotExist: return HttpResponseNotFound("User not found") closedAfter = -1 openedBefore = -1 if timearg is not None: timeargSplit = timearg.split(",") if len(timeargSplit) >= 1: closedAfter = int(timeargSplit[0]) if len(timeargSplit) >= 2: openedBefore = int(timeargSplit[1]) changesets = pgmap.vectorchangeset() errStr = pgmap.PgMapError() t = p.GetTransaction("ACCESS SHARE") ok = t.GetChangesets(changesets, int(user_uid), closedAfter, openedBefore, isOpenOnly, isClosedOnly, errStr) t.Commit() changesetLi = [] for i in range(len(changesets)): changesetLi.append(changesets[i]) return SerializeChangesets(changesetLi)
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