function remap_all_tags(&$input_osm_ways) { $input_nodes = $input_osm_ways->nodes; $input_ways = $input_osm_ways->ways; $result = new OSMWays(); $state_name_map = array(); foreach ($input_ways as $input_way) { $tags = $input_way['tags']; $new_tags = remap_way_tags($tags, $state_name_map); if (!isset($new_tags)) { continue; } $result->begin_way(); foreach ($input_way['nds'] as $nd_ref) { if (!isset($input_nodes[$nd_ref])) { continue; } $node = $input_nodes[$nd_ref]; $result->add_vertex($node['lat'], $node['lon']); } foreach ($new_tags as $key => $value) { $result->add_tag($key, $value); } $result->end_way(); } return $result; }
function crop_ways_to_box(&$input_osm_ways, $min_lat, $min_lon, $max_lat, $max_lon, $verbose) { if ($verbose) { error_log("Starting way cropping"); } $clipping_planes = get_clipping_planes_for_box($min_lat, $min_lon, $max_lat, $max_lon); $input_nodes = $input_osm_ways->nodes; $input_ways = $input_osm_ways->ways; $result = new OSMWays(); $count = 0; foreach ($input_ways as $input_way) { $count += 1; if ($verbose && $count % 1000 === 0) { error_log("Processing {$count}/" . count($input_ways)); } $nds = $input_way['nds']; if (empty($nds)) { continue; } $output_vertices = array(); foreach ($nds as $nd_ref) { $current_vertex = $input_nodes[$nd_ref]; $output_vertices[] = $current_vertex; } foreach ($clipping_planes as $plane) { $output_vertices = clip_vertices_against_plane($output_vertices, $plane, $verbose); } if (empty($output_vertices)) { continue; } $result->begin_way(); foreach ($input_way['tags'] as $key => $value) { $result->add_tag($key, $value); } foreach ($output_vertices as $vertex) { $result->add_vertex($vertex['lat'], $vertex['lon']); } if ($input_way['is_closed']) { $result->force_closed(); } $result->end_way(); } if ($verbose) { error_log("Finished way cropping"); } return $result; }
} $district_code = $district_map[$district_name]; if (!isset($constituency_map[$constituency_name])) { $constituency_map[$constituency_name] = count($constituency_map); } $constituency_code = $constituency_map[$constituency_name]; $output_osm_ways->begin_way(); $output_osm_ways->add_tag('name', $constituency_name); $output_osm_ways->add_tag('hk_district_code', $district_code); $output_osm_ways->add_tag('hk_constituency_code', $constituency_code); foreach ($way['nds'] as $nd_ref) { if (!isset($input_nodes[$nd_ref])) { continue; } $node = $input_nodes[$nd_ref]; $output_osm_ways->add_vertex($node['lat'], $node['lon']); } $output_osm_ways->end_way(); } $output_contents = $output_osm_ways->serialize_to_xml(); file_put_contents($osm_output, $output_contents) or die("Couldn't write file '{$output_osm_file}'"); $php_output_handle = fopen($php_output, "w") or die("Couldn't open {$php_output}\n"); fwrite($php_output_handle, '$hk_district_code_accepted_values = array(' . "\n"); foreach ($district_map as $name => $code) { fwrite($php_output_handle, ' "' . $code . '",' . "\n"); } fwrite($php_output_handle, ');' . "\n\n"); fwrite($php_output_handle, '$hk_constituency_code_accepted_values = array(' . "\n"); foreach ($constituency_map as $name => $code) { fwrite($php_output_handle, ' "' . $code . '",' . "\n"); }
function close_ways($input_osm_ways, $verbose, $tolerance, $debug) { if ($verbose) { error_log("Starting close_ways()"); } $bucket_debug = $debug && false; $bucket_grid = new BucketGrid($tolerance * 2); $input_ways =& $input_osm_ways->ways; $input_nodes =& $input_osm_ways->nodes; $way_index = 0; foreach ($input_ways as $way_id => &$way) { $way_index += 1; if ($verbose && $way_index % 100 === 0) { error_log("Bucketed {$way_index}/" . count($input_ways)); } if ($way['is_closed'] === true) { continue; } $nds = $way['nds']; $nds_count = count($nds); if ($nds_count < 2) { continue; } $start_index = 0; $end_index = $nds_count - 1; $start_nd_ref = $nds[$start_index]; $end_nd_ref = $nds[$end_index]; $start_node = $input_nodes[$start_nd_ref]; $end_node = $input_nodes[$end_nd_ref]; $start_lat = $start_node['lat']; $start_lon = $start_node['lon']; $end_lat = $end_node['lat']; $end_lon = $end_node['lon']; $start_data = array('way_id' => $way_id, 'nd_ref' => $start_nd_ref, 'index' => $start_index, 'lat' => $start_lat, 'lon' => $start_lon); $end_data = array('way_id' => $way_id, 'nd_ref' => $end_nd_ref, 'index' => $end_index, 'lat' => $end_lat, 'lon' => $end_lon); if ($bucket_debug) { error_log("insert_point({$start_lon}, {$start_lat}, " . print_r($start_data, true) . ")"); } $bucket_grid->insert_point($start_lon, $start_lat, $start_data, $bucket_debug); if ($bucket_debug) { error_log("insert_point({$end_lon}, {$end_lat}, " . print_r($end_data, true) . ")"); } $bucket_grid->insert_point($end_lon, $end_lat, $end_data, $bucket_debug); } if ($bucket_debug) { error_log("bucket_grid: " . print_r($bucket_grid->buckets, true)); } $result = new OSMWays(); $way_index = 0; foreach ($input_ways as $way_id => &$way) { $way_index += 1; if ($verbose && $way_index % 100 === 0) { error_log("Closing {$way_index}/" . count($input_ways)); } if ($way['is_closed'] === true) { if ($debug) { error_log("Found pre-closed way"); } $result->copy_way($way, $input_osm_ways); continue; } if (!empty($way['is_used'])) { if ($debug) { error_log("Found already used way"); } continue; } $input_tags = $way['tags']; if (count($way['nds']) < 2) { if ($debug) { error_log("Too few nodes found for {$way_id}"); } continue; } $start_index = 0; $start_way_id = $way_id; $start_nd_ref = $way['nds'][$start_index]; $start_node = $input_nodes[$start_nd_ref]; $follow_way_id = $way_id; $nds = $way['nds']; if ($debug) { error_log("Looking at {$follow_way_id}"); } $output_nds = array(); $loop_count = 0; while (true) { $input_ways[$follow_way_id]['is_used'] = true; $nds_count = count($nds); $end_index = $nds_count - 1; $output_nds = array_merge($output_nds, $nds); $end_nd_ref = $nds[$end_index]; $end_node = $input_nodes[$end_nd_ref]; if ($debug) { error_log("End node is {$end_nd_ref} at (" . $end_node['lat'] . "," . $end_node['lon'] . ")"); } $distance_to_start = get_node_distance($end_node, $start_node); // Have we looped back around to the start? if ($distance_to_start < $tolerance) { if ($debug) { error_log("Closed way starting with {$start_way_id}, ending with {$follow_way_id}"); } $output_nds[] = $start_nd_ref; $result->begin_way(); foreach ($output_nds as $nd_ref) { $node = $input_nodes[$nd_ref]; $result->add_vertex($node['lat'], $node['lon'], $bucket_debug); } foreach ($input_tags as $key => $value) { $result->add_tag($key, $value); } $result->end_way(); break; } // Figure out which lines we can connect to the end of this one $end_lat = $end_node['lat']; $end_lon = $end_node['lon']; $nearby_points = $bucket_grid->find_points_near($end_lon, $end_lat, $tolerance, $bucket_debug); if ($bucket_debug) { error_log("find_points_near({$end_lon}, {$end_lat}, {$tolerance}) returned " . print_r($nearby_points, true)); } $closest_distance = null; foreach ($nearby_points as $bucket_entry) { $point_data = $bucket_entry['data']; $point_lat = $point_data['lat']; $point_lon = $point_data['lon']; $point_way_id = $point_data['way_id']; $point_nd_ref = $point_data['nd_ref']; if ($point_nd_ref === $end_nd_ref && $point_way_id === $follow_way_id) { if ($bucket_debug) { error_log("{$point_nd_ref} was the same as the start"); } continue; } $distance = get_node_distance($point_data, $end_node); if ($bucket_debug) { error_log("{$point_nd_ref} was {$distance} away"); } if ($closest_distance === null || $distance < $closest_distance) { $closest_distance = $distance; } } // Have we reached the end of the line? if (!isset($closest_distance)) { if ($debug) { error_log("No close points found for {$follow_way_id}"); } break; } $found_nodes = array(); foreach ($nearby_points as $bucket_entry) { $point_data = $bucket_entry['data']; $point_lat = $point_data['lat']; $point_lon = $point_data['lon']; $point_way_id = $point_data['way_id']; $point_nd_ref = $point_data['nd_ref']; if ($point_nd_ref === $end_nd_ref && $point_way_id === $follow_way_id) { continue; } $distance = get_node_distance($point_data, $end_node); if ($distance < $closest_distance + EPSILON) { $found_nodes[] = $point_data; } } // Figure out which way edge to follow $found_nodes_count = count($found_nodes); if ($found_nodes_count === 1) { if ($debug) { error_log("A single close point found for {$follow_way_id}"); } $follow_node_index = 0; } else { if ($debug) { error_log("Too many close points found for {$follow_way_id}"); } break; } $follow_node = $found_nodes[$follow_node_index]; $follow_way_id = $follow_node['way_id']; $follow_way = $input_ways[$follow_way_id]; $do_reverse = $follow_node['index'] > 0; $nds = $follow_way['nds']; if ($do_reverse) { $nds = array_reverse($nds); } $loop_count += 1; if ($loop_count > 1000) { die("Looped too many times\n"); } } } if ($verbose) { error_log("Finished close_ways()"); } return $result; }
$osm_ways->begin_way(); foreach ($vertices as $vertex) { $x = $vertex['x']; $y = $vertex['y']; if ($convert_from_uk) { $geo = NEtoLL($x, $y); $lat = $geo['latitude']; $lon = $geo['longitude']; } else { if (isset($proj_convert)) { list($lon, $lat) = $proj_convert->lcc2ll(array($x, $y)); } else { $lat = $y; $lon = $x; } } $osm_ways->add_vertex($lat, $lon); } if (!is_array($current_attributes)) { die("Bad attributes: " . error_log(print_r($current_attributes, true))); } foreach ($current_attributes as $key => $value) { $osm_ways->add_tag($key, $value); } $osm_ways->end_way(); } } $osm_xml = $osm_ways->serialize_to_xml(); $output_file_handle = fopen($output_file, 'w') or die("Couldn't open {$output_file} for writing"); fwrite($output_file_handle, $osm_xml); fclose($output_file_handle);
function merge_nodes_on_edges($input_osm_ways, $verbose, $tolerance, $debug) { if ($verbose) { error_log("Starting merge_nodes_on_edges()"); } $bucket_debug = $debug; $input_ways =& $input_osm_ways->ways; $input_nodes =& $input_osm_ways->nodes; $result = new OSMWays(); $way_index = 0; foreach ($input_ways as $way_id => $way) { $way_index += 1; // if ($verbose&&(($way_index%100)===0)) error_log("Merged {$way_index}/" . count($input_ways)); $nds = $way['nds']; $nds_count = count($nds); if ($nds_count < 2) { $result->copy_way($way, $input_osm_ways); if ($debug) { error_log("Skipping {$way_id}"); } continue; } $result->begin_way($way_id); foreach ($way['tags'] as $key => $value) { $result->add_tag($key, $value); } $nds_map = array_count_values($nds); $node_index = 0; foreach ($nds as $nd_ref) { $is_last = $node_index == $nds_count - 1; $node_index += 1; if (!isset($input_nodes[$nd_ref])) { if ($debug) { error_log("Missing node {$nd_ref} in {$way_id}"); } continue; } $node = $input_nodes[$nd_ref]; $start_x = $node['lat']; $start_y = $node['lon']; if ($debug) { error_log("Adding original {$nd_ref} ({$start_x}, {$start_y})"); } $result->add_vertex($start_x, $start_y); if ($is_last) { continue; } $end_nd_ref = $nds[$node_index]; $end_node = $input_nodes[$end_nd_ref]; $end_x = $end_node['lat']; $end_y = $end_node['lon']; $coincident_points = $input_osm_ways->bucket_grid->find_points_near_line($start_x, $start_y, $end_x, $end_y, $tolerance, $bucket_debug); $sortfunction = create_function('$a, $b', 'if ($a["output_s"]>$b["output_s"]) return 1; else return -1;'); usort($coincident_points, $sortfunction); foreach ($coincident_points as $point) { $s = $point['output_s']; if ($s < 0.0 || $s > 1.0) { continue; } $point_nd_ref = $point['data']['id']; if (isset($nds_map[$point_nd_ref])) { continue; } if ($debug) { error_log("Adding {$point_nd_ref}"); } $point_x = $point['x']; $point_y = $point['y']; $result->add_vertex($point_x, $point_y); } } $result->end_way(); } if ($verbose) { error_log("Finished close_ways()"); } return $result; }
function decimate_ways($input_osm_ways, $decimate) { if ($decimate == 0) { return $input_osm_ways; } $frequency = 100.0 / $decimate; $result = new OSMWays(); $input_ways = $input_osm_ways->ways; $input_nodes = $input_osm_ways->nodes; foreach ($input_ways as $way) { $result->begin_way(); foreach ($way['tags'] as $key => $value) { $result->add_tag($key, $value); } $nds_count = count($way['nds']); $nd_index = 0; foreach ($way['nds'] as $nd_ref) { $is_first = $nd_index == 0; $is_last = $nd_index == $nds_count - 1; $nd_index += 1; if (!isset($input_nodes[$nd_ref])) { continue; } $mod = fmod($nd_index, $frequency); $is_keeper = $mod < 0.998; $use_vertex = $is_first || $is_last || $is_keeper; if ($use_vertex) { $node = $input_nodes[$nd_ref]; $result->add_vertex($node['lat'], $node['lon']); } } $result->end_way(); } return $result; }