def groupStopsByName(stops): stopsByName = [] for name, group in groupBy(stops, "name").items(): center = centerPoint(group) # TODO: more properties? # TODO: maybe draw line instead of just center point? properties = {"name": name, "stop_positions": len(group["features"])} stopByName = geojson.Feature(geometry=center, properties=properties) stopsByName.append(stopByName) return stopsByName
def getOpenAtMidnightThings(): thingsWithOpeningHour = next(OverPassHelper( ).directFetch(dresdenAreaId, [ OsmDataQuery("Midnight things", OsmObjectType.ALL, [ '"opening_hours"', '"highway"!~"."', '"tourism"!~"."', '"leisure"!~"park|fitness_centre|bowling_alley|play_ground|playground"', '"amenity"!~"parking|atm|hospital|charging_station|toilets|car_|vending_|bank|restaurant|bar$|pub$|nightclub|stripclub|brothel|cinema|theatre|drinking_water|nursing_home|recycling|shower|police|bicycle_|air|post_office"', '"shop"!~"hairdresser"', '"office"!~"."' ]) ])) # general problem: opening hours must be filled in and valid & what should be excluded specifically # TODO: easier to state what tags are allowed? midnightThings = groupBy( thingsWithOpeningHour, lambda props: isOpenAtMidnight(props["opening_hours"])) midnightThings.pop('False') return midnightThings
def getPublicStops(): overpassFetcher = OverPassHelper() pieschenAreaId = overpassFetcher.getAreaId("Dresden, Germany") logging.info("Get stops from openstreetmap") stopsOsmQuery = OsmDataQuery("Public Transport stops", OsmObjectType.NODE, ['"public_transport"="stop_position"']) stops = next(overpassFetcher.directFetch(pieschenAreaId, [stopsOsmQuery])) stopsByName = [] logging.info("Group stops by name") for name, group in groupBy(stops, "name").items(): center = centerPoint(group) # TODO: more properties? # TODO: maybe draw line instead of just center point? properties = {"name": name, "stop_positions": len(group["features"])} stopByName = geojson.Feature(geometry=center, properties=properties) stopsByName.append(stopByName) return stopsByName
overrideFiles=False) pieschenCoord = pieschen.toJSON()[0] map = folium.Map(location=[pieschenCoord["lat"], pieschenCoord["lon"]], tiles='Stamen Toner', zoom_start=15) # matplotlib colormap names colormaps = ["hsv", "BrBG", "coolwarm"] objectTypeTagMapping = { "streets": "highway", "buildings": "building", "landuse": "landuse" } for i, osmQuery in enumerate(osmDataFiles): file = open(osmQuery.filePath, encoding='UTF-8') allObjects = json.load(file) objectGroups = groupBy(allObjects, osmQuery.groupByProperty) objectMap = generateFeatureCollectionForGroups( objectGroups, colormaps[i % len(colormaps)], osmQuery.name) objectMap.add_to(map) folium.LayerControl().add_to(map) fileName = "out/maps/map_{}.html".format(areaName) map.save(fileName) print("Map saved in {}".format(fileName))
show=False).add_to(map) except FileNotFoundError: logging.error("run timeMapsRetriever to get time maps") # (34) change-points pattern = "Public Transport Change Points (Pattern 34)" logging.info(pattern) try: with open("out/data/dvbChangePoints.json", encoding='UTF-8') as file: changePoints = geojson.load(file) # replacing E as these are just substitute lines for another line like E8 and 8 changePointsPerLineCount = groupBy( changePoints, lambda props: len([ line for line in props.get("lines", []) if not line.strip().startswith("E") ])) changePointsPerLineCount.pop("1") changePointsPerLineCount = { "{} lines".format(k): v for k, v in changePointsPerLineCount.items() if int(k) > 1 } generateFeatureCollectionForGroups(changePointsPerLineCount, ['#000099', "#cc0099"], pattern, show=False).add_to(map) except FileNotFoundError: logging.error("run dvbRetriever to get info about change Points") ###################
def intersections(geoJsonFeatureCollection, idProperty="name", kindOfFeatures="stations", maxIterations=None): """ calculates every intersection of the geometries ... ! might take quite a while for geometries with many overlapping areas ! not raster based geoJsonFeatureCollection: input features on which intersections are calculated idProperty: property of the feature used for intersection describtion kindOfObjects: describtion of the features maxIterations: maximum of iterations to search for new intersections (aka maximum intersection depth) """ # TODO: allow alternative version based on rasters? # raster version: # 1. convex-hull or bounding box over all geoms # 2. raster convex hull with given precision # 3. iterate through each input geom and input raster # *4. union adjacent rasters if they have the same properties/geom-ids features = geoJsonFeatureCollection["features"] shapeMapping = { id: shapeFunc(feature["geometry"]) for id, feature in enumerate(features) } # add id attribute to shapes (for later reference when retrieved from index) for id, currentShape in shapeMapping.items(): currentShape.ids = set([id]) newIntersectionsFound = True shapes = shapeMapping.values() foundIntersections = set() result = list(shapes) iterations = 0 while newIntersectionsFound and not maxIterations == iterations: index = STRtree(shapes) newShapes = [] for currentShape in shapes: foundShapes = index.query(currentShape) # removes false positive from STRtree retrieval intersectionShapes = [ s for s in foundShapes if s.overlaps(currentShape) and not s == currentShape ] for otherShape in intersectionShapes: unionedIds = currentShape.ids.union(otherShape.ids) intersectionKey = tuple(sorted(list(unionedIds))) if intersectionKey in foundIntersections: # skipping intersection is not order specific, therefore intersection can be skipped continue else: foundIntersections.add(intersectionKey) newShape = currentShape.intersection(otherShape) if newShape.geometryType() == "Polygon": newShape.ids = unionedIds newShapes.append(newShape) elif newShape.geometryType( ) == 'GeometryCollection' or newShape.geometryType( ) == 'MultiPolygon': newShapeList = [ s for s in newShape if s.geometryType() == 'Polygon' and not s.is_empty ] for s in newShapeList: s.ids = unionedIds newShapes += newShapeList if not newShapes: newIntersectionsFound = False else: logging.debug("Found {} intersections".format(len(newShapes))) shapes = newShapes result += newShapes iterations += 1 resultFeatures = [] for shape in result: featureNames = { features[id]["properties"].get(idProperty, "unnamed") for id in shape.ids } properties = {kindOfFeatures: len(featureNames), "names": featureNames} resultFeatures.append(shapeGeomToGeoJson(shape, properties=properties)) resultGroups = groupBy(geojson.FeatureCollection(resultFeatures), kindOfFeatures) if newIntersectionsFound: logging.info("Terminated earlier due to set maxIterations") maxIntersections = max([int(k) for k in resultGroups.keys()]) resultGroups[">=" + str(maxIntersections)] = resultGroups.pop( str(maxIntersections)) return { "{} {}".format(k, kindOfFeatures): v for k, v in resultGroups.items() }
from OSMPythonTools.nominatim import Nominatim import folium from folium.plugins.measure_control import MeasureControl import sys, os sys.path.insert(1, os.path.abspath('..')) from helper.geoJsonHelper import groupBy from helper.overPassHelper import OverPassHelper from helper.OsmDataQuery import OsmDataQuery from helper.OsmObjectType import OsmObjectType pieschen = Nominatim().query('Pieschen, Dresden, Germany') osmQuery = OsmDataQuery("streets", OsmObjectType.WAY, ["'highway'"], "highway") all_streets = next(OverPassHelper().directFetch(pieschen.areaId(), [osmQuery])) street_types = groupBy(all_streets, ["highway"]) piescheonCoord = [pieschen.toJSON()[0]["lat"], pieschen.toJSON()[0]["lon"]] streetMap = folium.Map(location=piescheonCoord, tiles='Stamen Toner', zoom_start=15) icon = folium.Icon(icon="pills", color='lightgray', icon_color='red') folium.Marker(location=piescheonCoord, tooltip="test", icon=icon).add_to(streetMap) for type, streets in street_types.items(): properties = list(streets["features"][0]["properties"].keys()) folium.GeoJson( streets,