def ProjPoint(e, n): try: x,y,z= ostn02.OSGB36_to_ETRS89(e, n) return osgb.grid_to_ll(x,y) except: #Use approximation return osgb.grid_to_ll(e,n)
def ProcessTile(tileCode, userpass, baseurl, outFolder): fina = outFolder+"/"+tileCode+".osm.bz2" if os.path.exists(fina): return 0 tileBL = osgb.os_streetview_tile_to_grid(tileCode) tileTR = (tileBL[0]+5000, tileBL[1]+5000) tileBR = (tileBL[0]+5000, tileBL[1]) tileTL = (tileBL[0], tileBL[1]+5000) print "Grid corners" print tileBL, tileTR print tileBR, tileTL tileBLLatLon = ProjPoint(*tileBL) tileBRLatLon = ProjPoint(*tileBR) tileTRLatLon = ProjPoint(*tileTR) tileTLLatLon = ProjPoint(*tileTL) lats = [tileBLLatLon[0], tileBRLatLon[0], tileTRLatLon[0], tileTLLatLon[0]] lons = [tileBLLatLon[1], tileBRLatLon[1], tileTRLatLon[1], tileTLLatLon[1]] #print "lats",lats #print "lons",lons url = "http://fosm.org/api/0.6/map?bbox={0:.10f},{1:.10f},{2:.10f},{3:.10f}".format(min(lons),min(lats),\ max(lons),max(lats)) print url f = urllib2.urlopen(url) data = f.read() if len(data) > 0: outfi = bz2.BZ2File(fina, "w") outfi.write(data) outfi.close()
def DownloadOsTiles(tileCode1, tileCode2): tileCorner1 = osgb.os_streetview_tile_to_grid(tileCode1) print tileCorner1 tileCorner2 = osgb.os_streetview_tile_to_grid(tileCode2) print tileCorner2 er = range(int(tileCorner1[0]), int(tileCorner2[0]+5000), 5000) nr = range(int(tileCorner1[1]), int(tileCorner2[1]+5000), 5000) skipping = False for e in er: for n in nr: tileCode = osgb.grid_to_os_streetview_tile((e, n))[0] #if tileCode.upper() == "SO04SE": skipping = False if skipping is True: continue print e, n, tileCode ProcessTile(tileCode, userpass, baseurl, "existing/su")
def GetOsTile(tileCode = "so22nw", zoom = 12, out = None): tileBL = osgb.os_streetview_tile_to_grid(tileCode) tileTR = (tileBL[0]+5000, tileBL[1]+5000) tileBR = (tileBL[0]+5000, tileBL[1]) tileTL = (tileBL[0], tileBL[1]+5000) x,y,z= ostn02.OSGB36_to_ETRS89(*tileBL) c1 = osgb.grid_to_ll(x,y) x,y,z= ostn02.OSGB36_to_ETRS89(*tileTR) c2 = osgb.grid_to_ll(x,y) x,y,z= ostn02.OSGB36_to_ETRS89(*tileBR) c3 = osgb.grid_to_ll(x,y) x,y,z= ostn02.OSGB36_to_ETRS89(*tileTL) c4 = osgb.grid_to_ll(x,y) lat = [c1[0], c2[0], c3[0], c4[0]] lon = [c1[1], c2[1], c3[1], c4[1]] minLat, maxLat = min(lat), max(lat) minLon, maxLon = min(lon), max(lon) tilex1, tiley1 = slippytiles.deg2num(maxLat, minLon, zoom) tilex2, tiley2 = slippytiles.deg2num(minLat, maxLon, zoom) tilePath = "/home/tim/dev/batch-garmin-map/{0}/{1}/{2}.osm.bz2" fileList = [] for x in range(tilex1, tilex2+1): for y in range(tiley1, tiley2+1): fina = tilePath.format(zoom, x, y) print x, y, fina if os.path.isfile(fina): fileList.append(fina) mergeTiles.MergeFiles(fileList, out)
def ProjPoint(e, n): x,y,z= ostn02.OSGB36_to_ETRS89(e, n) return osgb.grid_to_ll(x,y)
def Dedup(fiHandle, tileCode, finaOut, finaExistingOutIn = None, finaExistingOut = "existing.osm"): newObjsXml = fiHandle.read() root = ET.fromstring(newObjsXml) newObjs = osm.OsmToShapely(root) tileBL = osgb.os_streetview_tile_to_grid(tileCode) tileTR = (tileBL[0]+5000, tileBL[1]+5000) tileBR = (tileBL[0]+5000, tileBL[1]) tileTL = (tileBL[0], tileBL[1]+5000) try: print "Grid corners" print tileBL, tileTR print tileBR, tileTL tileBLLatLon = ProjPoint(*tileBL) tileBRLatLon = ProjPoint(*tileBR) tileTRLatLon = ProjPoint(*tileTR) tileTLLatLon = ProjPoint(*tileTL) except: print "Transform error" return 0 lats = [tileBLLatLon[0], tileBRLatLon[0], tileTRLatLon[0], tileTLLatLon[0]] lons = [tileBLLatLon[1], tileBRLatLon[1], tileTRLatLon[1], tileTLLatLon[1]] print "lats",lats print "lons",lons fetchEnabled = True zapiOptimize = False if finaExistingOutIn is None: if not fetchEnabled: print "Input file missing", finaExistingOutIn exit(0) if zapiOptimize: #WARNING: xapi server does not necessarily update quickly! url = "http://fosm.org/api/0.6/*[natural=wood][bbox={0:.10f},{1:.10f},{2:.10f},{3:.10f}]".format(min(lons),min(lats),\ max(lons),max(lats)) existingWoods = urllib2.urlopen(url).read() url = "http://fosm.org/api/0.6/*[landuse=forest][bbox={0:.10f},{1:.10f},{2:.10f},{3:.10f}]".format(min(lons),min(lats),\ max(lons),max(lats)) existingForest = urllib2.urlopen(url).read() fi = open("existingWoods.osm","wt") fi.write(existingWoods) fi.close() fi = open("existingForest.osm","wt") fi.write(existingForest) fi.close() fi = open(finaExistingOut,"wt") mergeTiles.MergeFiles(["existingWoods.osm", "existingForest.osm"], fi) fi.close() fi = open(finaExistingOut,"r") existingXml = fi.read() else: url = "http://fosm.org/api/0.6/map?bbox={0:.10f},{1:.10f},{2:.10f},{3:.10f}".format(min(lons),min(lats),\ max(lons),max(lats)) existingXml = urllib2.urlopen(url).read() fi = open(finaExistingOut,"wt") fi.write(existingXml) fi.close() else: print finaExistingOutIn existingXml = None if finaExistingOutIn[-4:] == ".osm": existingXml = open(finaExistingOutIn,"rt").read() if finaExistingOutIn[-4:] == ".bz2": existingXml = bz2.BZ2File(finaExistingOutIn,"r").read() #existingWood = open("wood.osm","rt").read() #existingForest = open("forest.osm","rt").read() root = ET.fromstring(existingXml) #existing = osm.OsmToShapely(root) #existing.extend(osm.OsmToShapely(root)) existing = osm.OsmToShapely(root) #Filter existing objects to ensure they are valid existFilt = [] for exObj in existing: if exObj[0].is_valid: existFilt.append(exObj) else: tmp = [exObj[0].buffer(0)] tmp.extend(exObj[1:]) existFilt.append(tmp) #Check for overlaps nondupObjs = [] dupObjs = [] for newObj in newObjs: print newObj[1], newObj[2]#, newObj[0] ok = 1 for existingObj in existFilt: assert newObj[0].is_valid assert existingObj[0].is_valid hit = newObj[0].intersects(existingObj[0]) if hit: ok = 0 print "overlaps", existingObj[1], existingObj[2] if ok: nondupObjs.append((newObj[1], newObj[2])) else: dupObjs.append((newObj[1], newObj[2])) print "nondupObjs", nondupObjs #Write osm file without duplicates outTree = FilterOsm(newObjsXml, nondupObjs) outTree.write(finaOut) return 1
def JsonToOsm(fina, finaOut, margin, tileCode): finaSplit = os.path.split(fina) tileCode = finaSplit[-1][:6] tileDirParts = finaSplit[0].split("/")[:-1] tileDir = "" for partNum, part in enumerate(tileDirParts): tileDir += part + "/" tileCorner = osgb.os_streetview_tile_to_grid(tileCode) print tileCorner #Load json tiles for surrounding areas jsonTiles = [] tileCorners = [] tileCodes = [] for e in range(-5000, 10000, 5000): jsonTileRow = [] cornerRow = [] tileCodeRow = [] for n in range(-5000, 10000, 5000): iterTileCode = osgb.grid_to_os_streetview_tile((tileCorner[0]+e, tileCorner[1]+n))[0] tileFina = tileDir+iterTileCode[:2].lower() + "/" + iterTileCode.lower() + ".json.bz2" print "Load", tileFina if os.path.exists(tileFina): try: contentJson = bz2.BZ2File(tileFina).read() except: print "Error decoding bz2 in file:", tileFina continue try: decodedContent = json.loads(contentJson) except ValueError as err: print "Error decoding json in file:", tileFina continue jsonTileRow.append(decodedContent) cornerRow.append((tileCorner[0]+e-margin, tileCorner[1]+n-margin)) tileCodeRow.append(iterTileCode) else: print "Warning: tile not found", tileFina jsonTileRow.append(None) cornerRow.append(None) tileCodeRow.append(None) jsonTiles.append(jsonTileRow) tileCorners.append(cornerRow) tileCodes.append(tileCodeRow) #Convert to shapely tiles outerPolyTiles = [] for jsonTileRow, cornerRow, tileCodeRow in zip(jsonTiles, tileCorners, tileCodes): outerPolyTilesRow = [] for jsonTile, tileCorner, tc in zip(jsonTileRow, cornerRow, tileCodeRow): #print jsonTile, tileCorner, tc if tileCorner is not None: outerPolyTilesRow.append(GetShapelyPolygons(jsonTile, tileCorner[0], tileCorner[1], tc)) else: outerPolyTilesRow.append(None) outerPolyTiles.append(outerPolyTilesRow) print "Num outerPolyTiles", len(outerPolyTiles) #Exhaustively check for overlaps currentLayer = [] inRoi = [] centreTile = outerPolyTiles[1][1] for rowNum, outerPolyTilesRow in enumerate(outerPolyTiles): for colNum, outerPolys in enumerate(outerPolyTilesRow): isCentreTile = (rowNum == 1 and colNum == 1) if outerPolys is None: continue for poly in outerPolys: currentLayer.append(copy.deepcopy(poly)) inRoi.append(isCentreTile) for polyNum1 in range(len(currentLayer)): for polyNum2 in range(len(currentLayer)): if polyNum1 == polyNum2: continue poly1 = currentLayer[polyNum1] poly2 = currentLayer[polyNum2] if poly1 is None or poly2 is None: continue try: inters = poly1.intersects(poly2) except PredicateError: print "Warning: shapely.geos.PredicateError occured" inters = 0 if inters: print "Merging", polyNum1, "and", polyNum2 currentLayer[polyNum1] = currentLayer[polyNum1].union(poly2) #print type(currentLayer[polyNum1]) inRoi[polyNum1] = inRoi[polyNum1] or inRoi[polyNum2] currentLayer[polyNum2] = None inRoi[polyNum2] = False centreObjs = [] for poly, roi in zip(currentLayer, inRoi): if not roi: continue if poly is None: continue centreObjs.append(poly) if 0: out = PolysToOsm(currentLayer) outFi = open("currentLayer","wt") outFi.write(out) outFi.flush() #Simplify polygons print "Simplifying" simplifiedCentreObjs = [] for poly in centreObjs: tags = {} tags['natural'] = 'wood' simplifiedCentreObjs.append([poly.simplify(2.0, True), tags]) #Flag small polygons #for poly, tags in simplifiedCentreObjs: # # if isinstance(poly, MultiPolygon): # for ply in poly.geoms: # outerPolys.append(ply) # innerPolys.extend(ply.interiors) # else: # outerPolys = [poly] # innerPolys = poly.interiors # allPolys = outerPolys # allPolys.extend(innerPolys) # hit = 0 # for basicPoly in allPolys: # print "area", basicPoly.area # if basicPoly.area < 5e-9: # hit = 1 # if hit: # tags["import_area"] = "warning: contains small polygon" out = PolysToOsm(simplifiedCentreObjs) outFi = open(finaOut,"wt") outFi.write(out) outFi.flush() print "Output written to",finaOut