def buildFilledContourLayer(self, polygons, asLayers=False): name = self.uOutputName.text() zField = self._zField zmin=zField+'_min' zmax=zField+'_max' vl = self.createVectorLayer("MultiPolygon", name, FILLED, [('index',int), (zmin,float), (zmax,float), ('label',str) ]) pr = vl.dataProvider() fields = pr.fields() msg = list() symbols=[] ninvalid=0 dx,dy=self._origin for i, level_min, level_max, polygon in polygons: level_min=float(level_min) level_max=float(level_max) levels = ( self.formatLevel(level_min) + " - " + self.formatLevel(level_max) + self.uLabelUnits.text() ) try: feat = QgsFeature(fields) try: geom=MultiPolygon(polygon) if not geom.is_valid: # Try buffering to create a valid alternative for geometry # Test area is not significantly altered geom2=geom.buffer(0.0) if geom2.area > 0.0 and abs(1-geom.area/geom2.area) < 0.000001: geom=geom2 if not geom.is_valid: ninvalid += 1 qgeom=QgsGeometry.fromWkt(geom.to_wkt()) qgeom.translate(dx,dy) feat.setGeometry(qgeom) except: continue feat['index']=i feat[zmin]=level_min feat[zmax]=level_max feat['label']=levels pr.addFeatures( [ feat ] ) symbols.append([level_min,levels]) except Exception as ex: self.warnUser(ex.message) msg.append(unicode(levels)) if len(msg) > 0: self.warnUser("Levels not represented : "+", ".join(msg),"Filled Contour issue") if ninvalid > 0: self.warnUser("Matplotlib contouring routine has creating {0} invalid geometries" .format(ninvalid)) vl.updateExtents() vl.commitChanges() self.applyRenderer(vl,'polygon',zmin,symbols) return vl
def buildLayeredContourLayer(self, polygons, asLayers=False): name = "%s"%self.uOutputName.text() zfield = self._zField vl = self.createVectorLayer("MultiPolygon", name, LAYERS, [('index',int), (zfield,float), ('label',str) ]) pr = vl.dataProvider() fields = pr.fields() msg = list() symbols=[] ninvalid=0 dx,dy=self._origin for i, level_min, level_max, polygon in polygons: level_min=float(level_min) level_max=float(level_max) levels = self.formatLevel(level)+self.uLabelUnits.text() try: feat = QgsFeature(fields) try: geom=MultiPolygon(polygon) if not geom.is_valid: ninvalid += 1 qgeom=QgsGeometry.fromWkt(geom.to_wkt()) qgeom.translate(dx,dy) feat.setGeometry(qgeom) except: continue feat['index']=i feat[zfield]=level_min feat['label']=levels pr.addFeatures( [ feat ] ) symbols.append([level_min,levels]) except Exception as ex: self.warnUser(ex.message) msg.append(levels) if len(msg) > 0: self.warnUser("Levels not represented : "+", ".join(msg),"Layered Contour issue") if ninvalid > 0: self.warnUser("Matplotlib contouring routine has creating {0} invalid geometries" .format(ninvalid)) vl.updateExtents() vl.commitChanges() self.applyRenderer(vl,'polygon',zfield,symbols) return vl
def convert_to_multipolygon(geoms): from shapely.geometry import MultiPolygon rings = [] for geom in geoms: if isinstance(geom, MultiPolygon): rings = rings + [geom for geom in geom.geoms] else: rings = rings + [geom] geometry = MultiPolygon(rings) # Downsample 3D -> 2D wkt2d = geometry.to_wkt() geom2d = shapely.wkt.loads(wkt2d) return geom2d
def osmproxy(request): url = request.params.get("url") if url is None: return HTTPBadRequest() # instantiate parser and parser and start parsing parser = RelationParser() p = OSMParser(concurrency=1, coords_callback=parser.get_coords, relations_callback=parser.get_relations, ways_callback=parser.get_ways) temp = tempfile.NamedTemporaryFile(suffix='.osm') urllib.urlretrieve(url, temp.name) p.parse(temp.name) temp.close() polygons = [] r = parser.relation # first check for self closing ways for i in range(len(r) - 1, 0, -1): w = parser.ways[r[i]] if w[len(w) - 1] == w[0]: r.pop(i) nodes = [] polygon = Polygon([parser.nodes[node] for node in w]) polygons.append(polygon) if len(r) > 0: prev = parser.ways[r[0]] ordered_ways = [] ordered_ways.append(prev) r.pop(0) while len(r): match = False for i in range(0, len(r)): w = parser.ways[r[i]] # first node of the next way matches the last of the previous one if w[0] == prev[len(prev) - 1]: match = w # or maybe the way has to be reversed elif w[len(w) - 1] == prev[len(prev) - 1]: match = w[::-1] if match: prev = match ordered_ways.append(match) r.pop(i) break if len(ordered_ways) > 0: # now that ways are correctly ordered, we can create a unique geometry nodes = [] for way in ordered_ways: for node in way: nodes.append(parser.nodes[node]) # make sure that first and last node are similar if nodes[0] != nodes[len(nodes) - 1]: raise # create a shapely polygon with the nodes polygons.append(Polygon(nodes)) multipolygon = MultiPolygon(polygons) return Response(multipolygon.to_wkt())