示例#1
0
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')
示例#2
0
文件: views.py 项目: aaj013/pycrocosm
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')
示例#3
0
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
示例#4
0
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
示例#5
0
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
示例#6
0
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
示例#7
0
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
示例#8
0
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()
示例#9
0
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')
示例#10
0
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')
示例#11
0
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')
示例#12
0
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
示例#13
0
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')
示例#14
0
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')
示例#15
0
文件: views.py 项目: aaj013/pycrocosm
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')
示例#16
0
文件: tests.py 项目: aaj013/pycrocosm
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
示例#17
0
 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
示例#18
0
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')
示例#19
0
文件: tests.py 项目: aaj013/pycrocosm
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
示例#20
0
文件: tests.py 项目: aaj013/pycrocosm
    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")
示例#21
0
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
示例#22
0
文件: views.py 项目: aaj013/pycrocosm
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')
示例#23
0
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')
示例#24
0
            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()
示例#25
0
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