예제 #1
0
    def test_invalid_multilinestring(self):
        with self.assertRaises(ValueError) as cm:
            geojson.MultiLineString([1], validate=True)

        self.assertIn('each line must be a list of positions',
                      str(cm.exception))

        mls = geojson.MultiLineString([[(10, 5), (20, 1)], []])
        self.assertEqual(mls.is_valid, False)
예제 #2
0
 def test_invalid_multilinestring(self):
     multilinestring = geojson.MultiLineString()
     multilinestring.coordinates = [[D('100.0'), D('0.0')]]
     self.assertFalse(multilinestring.is_valid())
     multilinestring.coordinates = [[[D('100.0')], [D('101.0'),
                                                    D('1.0')]],
                                    [[D('102.0'), D('2.0')],
                                     [D('103.0'), D('3.0')]]]
     self.assertFalse(multilinestring.is_valid())
     multilinestring.coordinates = []
     self.assertFalse(multilinestring.is_valid())
     multilinestring = geojson.MultiLineString()
     self.assertFalse(multilinestring.is_valid())
예제 #3
0
def tryToConvertToPolygon(tags, lines, polygonize, isMultiPolygon = False):
    """
        Creates a Polygon or LineString based on the given lines
        tags: tags of the base object
        lines: coordinates (basically nested lists)
        polygonize: boolean, if True -> tries to convert every Line to Polygon
        isMultiPolygon: boolean, if each line is an extra polygon else lines = [boundary, holes..]
    """
    # as sometimes tags like "area":"no" exists, which are obviously no polygons
    tags = {tag: v for tag, v in tags.items() if not v == "no"}

    # osm-multipolygon: means just as complex area ... but geojson polygons can also handle holes
    # sometimes they are real multipolygons? (see Dresdener Heide) --> isMultiPolygon
    if POLYGON_TAGS.intersection(tags) or tags.get("type") == "multipolygon" or polygonize: 
        if isMultiPolygon:
            # creating a polygon array for each line (only exterior lines, no holes currently)
            lines = [[line] for line in lines]
            polygon = geojson.MultiPolygon(lines)
        else:
            polygon = geojson.Polygon(lines)
        if not polygon.errors():
            return polygon
        elif not polygonize:
            # with polygonize == true it is expected that this wont work every time
            logging.debug("Could not be converted to a polygon with tags {}".format(tags))
    if len(lines) == 1:
        return geojson.LineString(lines[0], validate=True)
    else:
        if LINESTRING_TAGS.intersection(tags):
            logging.debug("To many lines for a simple line for object with tags: {}".format(tags))
        return geojson.MultiLineString(lines, validate=True)
예제 #4
0
def toGeoJson(data, dtype):
    """formats all data input to valid geojson
    """
    dtype = dtype.lower()

    if dtype == "point":
        collection = []
        for i in range(0, len(data)):
            point = geojson.Point(data[i])
            collection.append(geojson.Feature(geometry=point))
        collection = geojson.FeatureCollection(collection)
        # pp.pprint(collection) # valid
        return collection

    if dtype == "polygon":
        polygon = geojson.Polygon(data)
        # print(polygon)  # valid
        return polygon

    elif dtype == "linestring":
        linestring = geojson.LineString(data)
        # print(linestring) #valid
        return (linestring)

    elif dtype == "multilinestring":
        mls = geojson.MultiLineString(data)
        # print(mls) # valid
        return mls

    else:
        print("\nBAD ARGUMENT\n")
예제 #5
0
def convertTOGEOJSON(data, ftype):
    """
    converts coordinates to geojson 

    """
    ftype = ftype.lower()

    if ftype == "point":
        result_feat = []
        for i in range(0, len(data)):
            point = geojson.Point(data[i])
            result_feat.append(geojson.Feature(geometry=point))
        result_feat = geojson.FeatureCollection(result_feat)
        # pp.pprint(collection) # valid
        return result_feat

    if ftype == "polygon":
        polygon = geojson.Polygon(data)
        # print(polygon)  # valid
        return polygon

    elif ftype == "linestring":
        linestring = geojson.LineString(data)
        # print(linestring) #valid
        return (linestring)

    elif ftype == "multilinestring":
        mls = geojson.MultiLineString(data)
        # print(mls) # valid
        return mls

    else:
        print("\nwrong argument\n")
예제 #6
0
def feature_to_polygons(feature):
    """
        given a geoJSON Feature object, convert it into Polygon(s). 
        A Feature object represents a spatially bounded thing. 
        In the GW case, these Features contains MultiLineStrings. 
        
        We build the polygons from the coordinates of each of those.
        
        Parameters:
        -----------
        
            feature: `geojson.Feature`
                object for which the coordinates will be folded.
        
        Returns:
        --------
        
            list of geojson.Polygon objects
    """
    
    # first fold the coordinates, all in one go.
    # perform the operation on a copy of the feature.
    folded = fold_coords(feature)
    
    # now convert to multiline string
    mls = geojson.MultiLineString(folded['geometry'], validate=True)
    if not mls.is_valid:
        raise ValueError("cannot convert feature geometry %s to valid geojson.MultiLineString"%
                         (repr(feature.coordinates)))
     
    # convert each coordinate list of the multilinestring to polygons and return
    return [to_poly([cc]) for cc in mls['coordinates']]
예제 #7
0
    def _convert_vector_field_to_geojson(self, vertices,
                                         vector_field_magnitude, vector_field,
                                         scale, cmap):
        """
        Convert a scalar field to a geojson FeatureCollection.

        Parameters
        ----------
        geo_map : folium.Map
            Map to which the mesh plot should be added.
        vertices: 2d numpy array
            Matrix containing the coordinates of the vertices.
            The matrix should have as many rows as vertices in the mesh, and two columns.
        vector_field_magnitude: 1d numpy array
            Vector containing the magnitude of the field at each vertex.
            The vector should have as many entries as vertices in the mesh.
        vector_field: 2d numpy array
            Matrix containing the value of the field at each vertex.
            The matrix should have as many rows as vertices in the mesh, and two columns.
        scale: number
            Scaling to be applied before drawing arrows.
        cmap: function
            Color map to be used.

        Returns
        -------
        geojson.FeatureCollection
            A geojson FeatureCollection representing the scalar field.
        """

        multiline_coordinates = dict()
        multiline_properties = dict()
        for v in range(vertices.shape[0]):
            coordinates = [
                self.transformer(*vertices[v, :]),
                self.transformer(*(vertices[v, :] +
                                   scale * vector_field[v, :]))
            ]
            color = cmap(vector_field_magnitude[v])
            # Store current coordinates
            if color not in multiline_coordinates:
                multiline_coordinates[color] = list()
            multiline_coordinates[color].append(coordinates)
            # Store current properties
            properties = {"color": color, "weight": 2}
            if color not in multiline_properties:
                multiline_properties[color] = properties
            else:
                assert multiline_properties[color] == properties

        multiline_features = list()
        for color in multiline_coordinates.keys():
            multiline = geojson.MultiLineString(
                coordinates=multiline_coordinates[color])
            feature = geojson.Feature(geometry=multiline,
                                      properties=multiline_properties[color])
            multiline_features.append(feature)

        return geojson.FeatureCollection(multiline_features)
예제 #8
0
def needs_reorienting():
    coords = [
        [(0.0, 0.0), (1.0, 0.0), (1.0, 1.0)],
        [(0.0, 0.0), (0.0, 1.0), (1.0, 1.0)],
    ]
    multi_line_string = geojson.MultiLineString(coords, validate=True)
    feature = geojson.Feature(geometry=multi_line_string, properties={})
    return geojson.FeatureCollection([feature])
예제 #9
0
def build_MultiLineString(G, pathlist):
    lines = []
    for path in pathlist:
        raw = nodes2coords(G, path)
        lines.append(raw)
    data = geojson.MultiLineString(lines)
    dump = geojson.dumps(data, sort_keys=True)
    return dump
예제 #10
0
def grid_lines_for_bbox(x_min, y_min, x_max, y_max, cells_x, cells_y):
    # top-down
    lines = list(gen_lines(x_min, x_max, y_min, y_max, cells_x))

    # left-right
    for _from, to in gen_lines(y_min, y_max, x_min, x_max, cells_y):
        lines.append([_from[::-1], to[::-1]])  # flip coordinates

    return geojson.MultiLineString(lines)
예제 #11
0
def test_get_center_point():
    assert util.get_center_point(
        geojson.Feature(
            geometry=geojson.LineString([[1, 0], [3, 0]]))) == (2.0, 0.0)

    assert util.get_center_point(
        geojson.Feature(geometry=geojson.MultiLineString(
            [[[2, 0], [2, 4]], [[0, 2], [4, 2]]]))) == (2.0, 2.0)
    assert util.get_center_point(
        geojson.Feature(geometry=geojson.Point([0, 0]))) == (None, None)
예제 #12
0
def create_feature(geometry,
                   geo_type,
                   val,
                   feature_id=None,
                   color=(255, 0, 0),
                   weight=10,
                   opacity=1.0,
                   props={}):
    """
    :param geometry: Geometry structure that creates geojson string.  Options are:
                     Point: (lng, lat) as tuple
                     MultiPoint: [Point, Point] as array of points
                     Line(string): [Point, Point, Point] as array of points
                     Multiline(string): [Line, Line] as array of lines
                     Polygon without holes: [Point1, Point, Point, Point1] as array of points,
                        first and last point in array are the same point (example makes a triangle).
                    Polygon with hole: [[Point1, Point, Point, Point1], [Point2, Point, Point, Point2]] as array of polygons,
                        second polygon is the hole.
                    Multipolygon: [Polygon, Polygon] as array of polygons (must confirm...?)
    :param geo_type: string indicating the geometry type, must match id strings from class geojson_geometry
    :param val: value to put into properties.value for mapping and style color matching
    :param feature_id: id for the geojson string
    :param color: a 3 value tuple containing an rgb value
    :param weight: for lines/polygons, line width; for points, point size
    :param opacity: opacity of layer in leaflet, 1.0 = 100%, 0 = 0%
    :returns: dictionary with geojson feature string and a leaflet style created from input parameters
    """

    try:
        if geo_type == GeojsonGeometry.point:
            geo = geojson.Point(geometry)
        elif geo_type == GeojsonGeometry.multipoint:
            geo = geojson.MultiPoint(geometry)
        elif geo_type == GeojsonGeometry.line:
            geo = geojson.LineString(geometry)
        elif geo_type == GeojsonGeometry.multiline:
            geo = geojson.MultiLineString(geometry)
        elif geo_type == GeojsonGeometry.polygon:
            geo = geojson.Polygon(geometry)
        elif geo_type == GeojsonGeometry.multipolygon:
            geo = geojson.MultiPolygon(geometry)
        else:
            print("Unsupported geometry type: " + geo_type)
            return
    except Exception as e:
        print(e, "\n probably wrong input data structure for " + geo_type)
        return

    style = None  # leaflet_style_creator()
    props['value'] = val
    geo = geojson.Feature(id=feature_id, geometry=geo, properties=props)

    ret = {'geojson': geo, 'style': style}

    return ret
 def test_fromgeojsonfeatures_multiline(self):
     g_f = geojson.Feature()
     line = geojson.MultiLineString(coordinates=[[[100.0, 0.0], [101.0, 1.0]], [[102.0, 2.0], [103.0, 3.0]]])
     g_f['properties'] = {"name": "name", "value": "value"}
     g_f['geometry'] = line
     g_fc = geojson.FeatureCollection([g_f])
     s_fs = from_geojson_features(g_fc)
     result = list(s_fs)
     self.assertEqual(result[0].geometry.parts, [2, 2])
     self.assertEqual(result[0].fieldNames, ['name', 'value'])
     self.assertEqual(result[0].fieldValues, ['name', 'value'])
예제 #14
0
def _topologize(input_features):
    r"""Return a FeatureCollection of MultiLineStrings, one for each loop"""
    loops = _features_to_loops(input_features)
    features = []
    for loop in loops:
        coords = [
            list(geojson.utils.coords(input_features[index])) for index in loop
        ]
        multi_line_string = geojson.MultiLineString(coords)
        features.append(geojson.Feature(geometry=multi_line_string))

    return features
예제 #15
0
def get_domain_geojson():
    """
    Return the domain as GeoJSON multipath.
    """
    domain = app.comm.project.domain

    outer_border = domain.border
    inner_border = domain.inner_border

    border = geojson.MultiLineString([
        [(_i[1], _i[0]) for _i in inner_border],
        [(_i[1], _i[0]) for _i in outer_border],
    ])
    return flask.jsonify(**border)
def ways2geometry(ways):
    """
    Convert a nested list of coordinates into a GeoJSON object.
    """
    if len(ways) == 1:
        way = ways[0]
        highway = way.get('highway')
        if ((way.get('area', '') == 'yes' and highway == 'pedestrian')
                or (way.get('leisure') in ['park', 'pitch', 'common'])):
            # See http://wiki.openstreetmap.org/wiki/Key:area
            return geojson.Polygon([way['coordinates']])
        elif highway:
            return geojson.LineString(way['coordinates'])
    else:
        return geojson.MultiLineString([w['coordinates'] for w in ways])
예제 #17
0
    def __init__(self, geom_type, zoom, m):
        proj = mapnik.Projection(m.srs)
        width_of_world_in_pixels = 2**zoom * 256
        width_of_world_in_metres = proj.forward(mapnik.Coord(
            180, 0)).x - proj.forward(mapnik.Coord(-180, 0)).x
        width_of_image_in_metres = float(
            m.width) / width_of_world_in_pixels * width_of_world_in_metres
        height_of_image_in_metres = float(
            m.height) / width_of_world_in_pixels * width_of_world_in_metres

        self.max_x = width_of_image_in_metres
        self.max_y = height_of_image_in_metres
        self.min_x = 0
        self.min_y = 0

        if geom_type == "point":
            self.geom = geojson.Point((self.max_x / 2, self.max_y / 2))
        elif geom_type == "point75":
            self.geom = geojson.Point((self.max_x * 0.5, self.max_y * 0.75))
        elif geom_type == "polygon":
            self.geom = geojson.Polygon([[(0, 0), (self.max_x, 0),
                                          (self.max_x, self.max_y),
                                          (0, self.max_y), (0, 0)]])
        elif geom_type == "linestring-with-gap":
            self.geom = geojson.MultiLineString([[
                (0, 0.5 * self.max_y), (self.max_x * 0.45, 0.5 * self.max_y),
                (self.max_x * 0.55, 0.5 * self.max_y),
                (self.max_x, 0.5 * self.max_y)
            ]])
        elif geom_type == "polygon-with-hole":
            self.geom = geojson.Polygon([[[0.7 * self.max_x, 0.2 * self.max_y],
                                          [0.9 * self.max_x, 0.9 * self.max_y],
                                          [0.3 * self.max_x, 0.8 * self.max_y],
                                          [0.2 * self.max_x, 0.4 * self.max_y],
                                          [0.7 * self.max_y,
                                           0.2 * self.max_y]],
                                         [[0.4 * self.max_x, 0.6 * self.max_y],
                                          [0.7 * self.max_x, 0.7 * self.max_y],
                                          [0.6 * self.max_x, 0.4 * self.max_y],
                                          [0.4 * self.max_x,
                                           0.6 * self.max_y]]])
        elif geom_type == "linestring":
            self.geom = geojson.LineString([[0, 0.5 * self.max_y],
                                            [self.max_x, 0.5 * self.max_y]])
        else:
            raise MapnikLegendaryError(
                "Geometry type {} is not supported for legend entries.".format(
                    geom_type))
예제 #18
0
파일: utils.py 프로젝트: ml242/process
def download_arcgis(url, gtype, pkey, filename):
    """
    Downloads from an ArcGIS REST API query endpoint and shows a simple progress bar.
    Endpoint must support pagination.

    :param url: resource to download
    :param gtype: geometry type
    :param pkey: the primary key for the data to download
    :param filename: destination filename (full path)
    :returns: Path to file
    """

    features = []
    where = pkey + " IS NOT NULL"

    count = requests.get(url, params={"f": "json", "where": where, "returnCountOnly": True})
    count = count.json()["count"]
    count = int(math.ceil(float(count) / 1000.0))

    print("[", end='')
    num = 0
    print_every_iter = int(count) / 50
    next_print = 0
    while num < count:
        data = requests.get(url, params={"f": "json", "where": where, "outFields": "*",
            "returnGeometry": True, "resultRecordCount": 1000, "resultOffset": (num * 1000)})
        data = data.json()["features"]
        num += 1
        features += data
        if num >= next_print:
            sys.stdout.write("=")
            sys.stdout.flush()
            next_print += print_every_iter

    with open(filename, "wb") as f:
        processed_features = []
        for x in features:
            if gtype == "point" and 'NaN' in [x["geometry"]["x"], x["geometry"]["y"]]:
                continue
            feat = geojson.Feature(id=x["attributes"][pkey], properties=x["attributes"],
                geometry=geojson.Point((x["geometry"]["x"], x["geometry"]["y"]))\
                    if gtype == "point" else geojson.MultiLineString(x["geometry"]["paths"]))
            processed_features.append(feat)
        processed_features = geojson.FeatureCollection(processed_features)
        geojson.dump(processed_features, f)

    print("] Download complete...")
    return filename
예제 #19
0
    def test_nested_constructors(self):
        a = [5, 6]
        b = [9, 10]
        c = [-5, 12]
        mp = geojson.MultiPoint([geojson.Point(a), b])
        self.assertEqual(mp.coordinates, [a, b])

        mls = geojson.MultiLineString([geojson.LineString([a, b]), [a, c]])
        self.assertEqual(mls.coordinates, [[a, b], [a, c]])

        outer = [a, b, c, a]
        poly = geojson.Polygon(geojson.MultiPoint(outer))
        other = [[1, 1], [1, 2], [2, 1], [1, 1]]
        poly2 = geojson.Polygon([outer, other])
        self.assertEqual(geojson.MultiPolygon([poly, poly2]).coordinates,
                         [[outer], [outer, other]])
예제 #20
0
 def get_features(self, tags):
     ls = self.wh.geojson_linestrings(properties=tags, as_features=False)
     if ls:
         ml = geojson.MultiLineString(ls)
         mlf = geojson.Feature(geometry=ml, properties=tags)
         # mlf = self.wh.geojson_linestrings(properties=tags, as_features=True)
     else:
         mlf = []
     pf = self.nh.geojson_features
     print(tags.get('name', ''))
     print('nh len features', len(self.nh.geojson_features))
     print('wh len features', len(self.wh.geojson_features))
     self.nh.geojson_features = list()
     self.wh.geojson_features = list()
     # print('nh len features',len(self.nh.geojson_features))
     # print('wh len features',len(self.wh.geojson_features))
     return pf, mlf
예제 #21
0
def dump_geojson(route, relation):
    """
    Writes the route relation as a GeoJSON file.

    :param route: Name of the route.
    :param relation: Route relation to dump to GeoJSON.
    """
    features = []
    multi_line_string = geojson.MultiLineString([[(node.lon, node.lat)
                                                  for node in way.nodes]
                                                 for way in relation.ways])
    properties = relation.tags if relation.tags is not None else dict()
    properties['@id'] = 'relation/' + str(relation.id)
    features.append(
        geojson.Feature(geometry=multi_line_string, properties=properties))

    with open(OSM_ROUTES_LOCATION + route + ".geojson", "w") as fp:
        fp.write(geojson.dumps(geojson.FeatureCollection(features)))
예제 #22
0
def createGeojson(data, name, ulx, uly, lrx, lry, projection):
    col = ['coordinate', 'type', 'label', 'pix']
    df = pd.DataFrame(data, columns=col)

    geofilename = name + ".geojson"
    filenameData = geofilename.split("_")

    features = []
    for name, row in df.iterrows():
        coords_pol = row['coordinate']
        if row['type'] == 'Polygon':
            if coords_pol[-1] != coords_pol[0]:
                coords_pol.append(coords_pol[0])
            features.append(
                geojson.Feature(properties={
                    'label': row['label'],
                    'filename': geofilename,
                    'country': filenameData[0],
                    'city': filenameData[1],
                    'image_geocoordinates_upper_left': [ulx, uly],
                    'image_geocoordinates_lower_right': [lrx, lry],
                    'pixel_coordinates': row['pix'],
                    'projection': projection
                },
                                geometry=geojson.Polygon([coords_pol])))
        elif row['type'] == 'Line':
            features.append(
                geojson.Feature(properties={
                    'label': row['label'],
                    'filename': geofilename,
                    'country': filenameData[0],
                    'city': filenameData[1],
                    'image_geocoordinates_upper_left': [ulx, uly],
                    'image_geocoordinates_lower_right': [lrx, lry],
                    'pixel_coordinates': row['pix'],
                    'projection': projection
                },
                                geometry=geojson.MultiLineString([coords_pol
                                                                  ])))

    f_coll = geojson.FeatureCollection(features)

    with open(geofilename, 'w') as f:
        json.dump(f_coll, f, indent=2)
def convert_json_data_to_geodataframe(json_data, spatial_reference='4326'):
    """Convert raw JSON objects from EDDM to a GeoDataFrame."""
    features = []

    for feature in json_data:
        new_feature = {}

        # Assume the feature is a LineString object.
        try:
            new_feature['geometry'] = shapely.geometry.shape(
                geojson.MultiLineString(feature['geometry']['paths']))
        # If the feature is not a LineString, maybe it is a MultiPoint.
        except KeyError:
            new_feature['geometry'] = shapely.geometry.shape(
                geojson.MultiPoint(feature['geometry']['points']))
        new_feature['properties'] = feature['attributes']
        features.append(new_feature)

    return gpd.GeoDataFrame.from_features(features, crs=spatial_reference)
예제 #24
0
def paths_geojson(city):

    paths = open(
        'static/data/' + str(city) + '/footfall/walking_paths_complete.csv',
        'r')
    paths = paths.readlines()
    json_paths = []
    for path in paths:
        new_path = []
        points = path.split(';')[:-1]
        for point in points:
            [lng, lat] = point.split(',')
            new_path.append((float(lat), float(lng)))
        json_paths.append(new_path)

    geojson_paths = geojson.MultiLineString(json_paths)
    geojson_data = geojson.dumps(geojson_paths)
    output_file = open(
        'static/data/' + str(city) + '/footfall/walking_paths.geojson', 'w')
    output_file.write(geojson_data)
예제 #25
0
def dump_bboxes(points, filename):
    fc = geojson.FeatureCollection([])

    for st, pts in points.items():
        if len(pts) == 0:
            continue

        lbot, rtop = bounding_box_naive(pts)
        llon, llat = lbot
        rlon, rlat = rtop
        print(st, lbot, rtop)

        f = geojson.Feature(geometry=geojson.MultiLineString([[(llat, llon),
                                                               (rlat, llon),
                                                               (rlat, rlon),
                                                               (llat, rlon),
                                                               (llat, llon)]]),
                            properties={'station_id': st})
        fc.features.append(f)
    with open(filename, "wb") as jfile:
        gj = geojson.dumps(fc, indent=4).encode("utf8")
        jfile.write(gj)
예제 #26
0
 def createGeoJSON(self):
     """ Get list of link geometries and properties to be converted.
         Input: Vissim object
         Output: list of links
     """
     features = []
     for link in self.data.xpath('./links/link'):
         geos = []
         linkNum = link.attrib['no']
         for geo in link.xpath('./geometry/points3D/point3D'):
             x, y = geo.attrib['x'], geo.attrib['y']
             latLng = self.scaledMetersToNode((x, y))
             geos.append(latLng)
         linkNum = link.attrib['no']
         laneNum = str(len(link.xpath('./lanes/lane')))
         multiLine = geojson.MultiLineString(coordinates=geos)
         features.append(
             geojson.Feature(id=linkNum,
                             geometry=multiLine,
                             properties={
                                 'lane': laneNum,
                                 'id': linkNum
                             }))
     return geojson.FeatureCollection(features)
예제 #27
0
def get_border(key, keywords):
    resjson = get_resjson(key, keywords, 0, 'all')
    district = resjson["districts"][0]
    if 'polyline' not in district:
        return {}
    cords = district['polyline'].split('|')
    polylines = []
    for cord in cords:
        lonlats = cord.split(';')
        polyline = []
        for lonlat in lonlats:
            lon, lat = lonlat.split(',')
            point = gcj02_to_wgs84(float(lon), float(lat))
            polyline.append(point)
        polylines.append(polyline)
    geom = geojson.MultiLineString(polylines)  # 多边形的拓扑关系不明,故使用线
    properties = {'citycode': district['citycode'],
                  'adcode': district['adcode'],
                  'name': district['name'],
                  'level': district['level']}
    border = {"type": "Feature",
              "properties": properties,
              "geometry": geom}
    return border
예제 #28
0
 def test_valid_multilinestring(self):
     ls1 = [(3.75, 9.25), (-130.95, 1.52)]
     ls2 = [(23.15, -34.25), (-1.35, -4.65), (3.45, 77.95)]
     mls = geojson.MultiLineString([ls1, ls2])
     self.assertEqual(is_valid(mls)['valid'], YES)
예제 #29
0
 def test_invalid_multilinestring(self):
     mls = geojson.MultiLineString([[(10, 5), (20, 1)], []])
     self.assertEqual(is_valid(mls)['valid'], NO)
예제 #30
0
def create_segments_from_json(roads_shp_path, mapfp):

    data = fiona.open(roads_shp_path)
    data = util.reproject_records([x for x in data])

    # All the line strings are roads
    roads = [x for x in data if x['geometry'].type == 'LineString']

    print("read in {} road segments".format(len(roads)))

    # unique id did not get included in shapefile, need to add it for adjacency
    for i, road in enumerate(roads):
        road['properties']['orig_id'] = int(str(99) + str(i))

    # Get the intersection list by excluding anything that's not labeled
    # as an intersection
    inters = [
        x for x in data if x['geometry'].type == 'Point' and 'intersection' in
        list(x['properties'].keys()) and x['properties']['intersection']
    ]

    # Initial buffer = 20 meters
    int_buffers = get_intersection_buffers(inters, 20)

    non_int_lines, inter_segments = find_non_ints(roads, int_buffers)

    non_int_w_ids = []

    # Allow intersections that don't have osmids, because this
    # happens when we generate alternate maps from city data
    # They won't have display names, and this is okay, because
    # we only use them to map to the osm segments
    inters_by_id = {
        x['properties']['osmid'] if 'osmid' in x['properties'] else '0':
        x['properties']['streets'] if 'streets' in x['properties'] else None
        for x in inters
    }

    for i, l in enumerate(non_int_lines):
        value = copy.deepcopy(l)
        value['type'] = 'Feature'
        value['properties']['id'] = '00' + str(i)
        value['properties']['inter'] = 0
        value['properties']['display_name'] = get_non_intersection_name(
            l, inters_by_id)
        non_int_w_ids.append(value)

    print("extracted {} non-intersection segments".format(len(non_int_w_ids)))

    # Planarize intersection segments
    # Turns the list of LineStrings into a MultiLineString
    union_inter = []

    for idx, lines in list(inter_segments['lines'].items()):

        lines = unary_union(lines)

        coords = []
        for line in lines:
            coords += [[x for x in line.coords]]

        name = get_intersection_name(inter_segments['data'][idx])
        properties = {
            'id': idx,
            'data': inter_segments['data'][idx],
            'display_name': name
        }

        union_inter.append(
            geojson.Feature(
                geometry=geojson.MultiLineString(coords),
                id=idx,
                properties=properties,
            ))
    return non_int_w_ids, union_inter