예제 #1
0
def strip_endpoints(filename):
    """
    If we are using an osm node file, strip out endpoints and write out
    to inters.shp
    """
    nodes = fiona.open(filename)
    intersections = [(Point(n['geometry']['coordinates']), n['properties'])
                     for n in nodes if not n['properties']['dead_end']]

    util.write_shp(nodes.schema,
                   os.path.join(MAP_FP, 'inters.shp'),
                   intersections,
                   0,
                   1,
                   crs=nodes.crs)
def get_signals():
    nodes = util.read_shp(
        os.path.join(MAP_FP, 'all_nodes', 'nodes', 'nodes.shp'))
    signals = [
        node for node in nodes if node[1]['highway'] == 'traffic_signals'
    ]
    schema = {
        'geometry': 'Point',
        'properties': {
            'highway': 'str',
            'osmid': 'str',
            'ref': 'str'
        }
    }
    util.write_shp(schema,
                   os.path.join(MAP_FP, 'osm_signals.shp'),
                   signals,
                   0,
                   1,
                   crs=fiona.crs.from_epsg(3857))
예제 #3
0
def create_segments(roads_shp_path, print_buffers=False):

    inters_shp_path_raw = os.path.join(MAP_FP, 'inters.shp')
    inters_shp_path = os.path.join(MAP_FP, 'inters_3857.shp')

    inters = reproject_and_read(inters_shp_path_raw, inters_shp_path)

    # Read in boston segments + mass DOT join
    roads = [(shape(road['geometry']), road['properties'])
             for road in fiona.open(roads_shp_path)]
    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[1]['orig_id'] = int(str(99) + str(i))

    # Initial buffer = 20 meters
    int_buffers = get_intersection_buffers(inters, 20)
    if print_buffers:
        # create new schema that has only an 'id' property of type string
        buff_schema = {
            'geometry': 'Polygon',
            'properties': {},
        }
        # write out shapefile that has intersection buffers
        util.write_shp(buff_schema, os.path.join(MAP_FP, 'int_buffers.shp'),
                       [(x, {}) for x in int_buffers], 0, 1)

    non_int_lines, inter_segments = find_non_ints(roads, int_buffers)

    # Planarize intersection segments
    # Turns the list of LineStrings into a MultiLineString
    union_inter = [({
        'id': idx
    }, unary_union(l)) for idx, l in inter_segments['lines'].items()]

    print "extracted {} intersection segments".format(len(union_inter))

    # Intersections shapefile
    inter_schema = {
        'geometry': 'LineString',
        'properties': {
            'id': 'int'
        },
    }
    util.write_shp(inter_schema, os.path.join(MAP_FP, 'inters_segments.shp'),
                   union_inter, 1, 0)

    # The inters_segments shapefile above only gives an id property
    # Store the other properties from inters_segments as json file
    with open(os.path.join(DATA_FP, 'inters_data.json'), 'w') as f:
        json.dump(inter_segments['data'], f)

    # add non_inter id format = 00+i
    non_int_w_ids = []
    i = 0

    for l in non_int_lines:
        prop = copy.deepcopy(l[1])
        prop['id'] = '00' + str(i)
        prop['inter'] = 0
        non_int_w_ids.append(tuple([l[0], prop]))
        i += 1
    print "extracted {} non-intersection segments".format(len(non_int_w_ids))

    # Non-intersection shapefile
    road_properties = {k: 'str' for k, v in non_int_w_ids[0][1].items()}
    road_schema = {'geometry': 'LineString', 'properties': road_properties}
    util.write_shp(road_schema, os.path.join(MAP_FP,
                                             'non_inters_segments.shp'),
                   non_int_w_ids, 0, 1)

    # Create shapefile that combines intersections and non-intersections while
    # preserving their newly created IDs

    # need to make the schema consistent between the two
    # for now, just keep the ids for the non-intersection segments
    # to keep things simple
    non_int_no_prop = []
    for i in non_int_w_ids:
        id = i[1]['id']

        # reverse the order of the tuple
        # while we're at it to make it
        # consistent with union_inter
        non_int_no_prop.append(({'id': id}, i[0]))

    # concatenate the two datasets
    inter_and_non_int = union_inter + non_int_no_prop

    # create new schema that has only an 'id' property of type string
    all_schema = {
        'geometry': 'LineString',
        'properties': {
            'id': 'str'
        },
    }

    # write out shapefile that has intersection and non-intersection segments
    # along with their new IDs
    util.write_shp(all_schema, os.path.join(MAP_FP, 'inter_and_non_int.shp'),
                   inter_and_non_int, 1, 0)

    return inter_segments['data']
예제 #4
0
        new_buffered.append((b, new_line[0], new_line[1]))
        new_index.insert(idx, b.bounds)

    non_ints_with_candidates = get_candidates(new_buffered, new_index,
                                              orig_map_non_inter)

    print "Adding features: " + ','.join(feats)
    get_mapping(non_ints_with_candidates, feats)

    # Write the non-intersections segments back out with the new features
    schema = {
        'geometry': 'LineString',
        'properties': {k: 'str'
                       for k in orig_map_non_inter[0][1].keys()}
    }
    util.write_shp(schema, os.path.join(MAP_FP, 'non_inters_segments.shp'),
                   orig_map_non_inter, 0, 1)

    # Now do intersections
    orig_map_inter = util.read_shp(
        os.path.join(MAP_FP, 'inters_segments_orig.shp'))

    new_map_inter = util.read_shp(
        os.path.join(MAP_FP, args.map2dir, 'inters_segments.shp'))

    orig_buffered_inter = []
    orig_index_inter = rtree.index.Index()

    new_buffered_inter = []
    new_index_inter = rtree.index.Index()
    for idx, new_line in enumerate(new_map_inter):
        b = new_line[0].buffer(10)
    # Planarize intersection segments
    union_inter = [({
        'id': idx
    }, unary_union(l)) for idx, l in inter_segments['lines'].items()]
    print "extracted {} intersection segments".format(len(union_inter))

    # Intersections shapefile
    inter_schema = {
        'geometry': 'LineString',
        'properties': {
            'id': 'int'
        },
    }

    write_shp(inter_schema, MAP_FP + '/inters_segments.shp', union_inter, 1, 0)

    # Output inters_segments properties as json
    with open(DATA_FP + '/inters_data.json', 'w') as f:
        json.dump(inter_segments['data'], f)

    # add non_inter id format = 00+i
    non_int_w_ids = []
    i = 0
    for l in non_int_lines:
        prop = copy.deepcopy(l[1])
        prop['id'] = '00' + str(i)
        non_int_w_ids.append(tuple([l[0], prop]))
        i += 1
    print "extracted {} non-intersection segments".format(len(non_int_w_ids))
예제 #6
0
                             orig=pyproj.Proj(init='epsg:4326')))
    print "Read in data from {} concerns".format(len(concern))

    combined_seg, segments_index = util.read_segments()

    # Find nearest crashes - 30 tolerance
    print "snapping crashes to segments"
    util.find_nearest(crash, combined_seg, segments_index, 30)

    # Find nearest concerns - 20 tolerance
    print "snapping concerns to segments"
    util.find_nearest(concern, combined_seg, segments_index, 20)

    # Write concerns
    concern_schema = make_schema('Point', concern[0]['properties'])
    print "output concerns shp to ", MAP_FP
    util.write_shp(concern_schema, MAP_FP + '/concern_joined.shp', concern,
                   'point', 'properties')
    print "output concerns data to ", PROCESSED_DATA_FP
    with open(PROCESSED_DATA_FP + '/concern_joined.json', 'w') as f:
        json.dump([c['properties'] for c in concern], f)

    # Write crash
    crash_schema = make_schema('Point', crash[0]['properties'])
    print "output crash shp to ", MAP_FP
    util.write_shp(crash_schema, MAP_FP + '/crash_joined.shp', crash, 'point',
                   'properties')
    print "output crash data to ", PROCESSED_DATA_FP
    with open(PROCESSED_DATA_FP + '/crash_joined.json', 'w') as f:
        json.dump([c['properties'] for c in crash], f)
def reproject_and_clean_feats(orig_file, result_file, DOC_FP):
    """
    Reads in osm_ways file, cleans up the features, and reprojects
    results into 3857 projection
    Additionally writes a key which shows the correspondence between
    highway type as a string and the resulting int feature
    Features:
        width
        lanes
        hwy_type
        osm_speed
        signal
    Args:
        orig_file: Filename for original file
        result_file: Filename for resulting file in 3857 projection
        DOC_FP: directory to write highway keys file to
    Returns:
        None, writes to file
    """

    way_results = fiona.open(orig_file)

    # Convert the map from above to 3857
    reprojected_way_lines = [
        tuple(x.values()) for x in util.reproject_records(way_results)
    ]

    highway_keys = {}
    for way_line in reprojected_way_lines:
        # All features need to be ints, so convert them here

        # Use speed limit if given in osm
        speed = way_line[1]['maxspeed']
        if speed:
            s = re.search('[0-9]+', speed)
            if s:
                speed = s.group(0)
        if not speed:
            speed = 0

        # round width
        width = 0
        if ['width'] in way_line[1].keys():
            width = way_line[1]['width']
            if not width or ';' in width or '[' in width:
                width = 0
            else:
                width = round(float(width))

        lanes = way_line[1]['lanes']
        if lanes:
            lanes = max([int(x) for x in re.findall('\d', lanes)])
        else:
            lanes = 0

        # Need to have an int highway field
        if way_line[1]['highway'] not in highway_keys.keys():
            highway_keys[way_line[1]['highway']] = len(highway_keys)

        # Use oneway
        oneway = 0
        if way_line[1]['oneway'] == 'True':
            oneway = 1

        way_line[1].update({
            'width': width,
            'lanes': int(lanes),
            'hwy_type': highway_keys[way_line[1]['highway']],
            'osm_speed': speed,
            'signal': 0,
            'oneway': oneway
        })
    schema = way_results.schema

    # Add values to schema if they don't exist, so new map won't break
    schema['properties'].update({
        # Add highway type key and osm_speed to the schema
        'width': 'int',
        'lanes': 'int',
        'hwy_type': 'int',
        'osm_speed': 'int',
        'signal': 'int',
        'oneway': 'int',
    })

    util.write_shp(schema,
                   result_file,
                   reprojected_way_lines,
                   0,
                   1,
                   crs=fiona.crs.from_epsg(3857))

    # Write highway keys to docs if needed for reference
    if not os.path.exists(DOC_FP):
        os.makedirs(DOC_FP)
    with open(os.path.join(DOC_FP, 'highway_keys.csv'), 'wb') as f:
        w = csv.writer(f)
        w.writerow(['type', 'value'])
        for item in highway_keys.iteritems():
            w.writerow(item)