kopia lustrzana https://github.com/onthegomap/planetiler
180 wiersze
3.9 KiB
Java
180 wiersze
3.9 KiB
Java
package com.onthegomap.planetiler.reader.osm;
|
|
|
|
import com.carrotsearch.hppc.LongArrayList;
|
|
import com.onthegomap.planetiler.geo.GeoUtils;
|
|
import com.onthegomap.planetiler.reader.WithTags;
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Objects;
|
|
|
|
/**
|
|
* An input element read from OpenStreetMap data.
|
|
*
|
|
* @see <a href="https://wiki.openstreetmap.org/wiki/Elements">OSM element data model</a>
|
|
*/
|
|
public interface OsmElement extends WithTags {
|
|
|
|
/** OSM element ID */
|
|
long id();
|
|
|
|
int cost();
|
|
|
|
enum Type {
|
|
NODE,
|
|
WAY,
|
|
RELATION
|
|
}
|
|
|
|
/** An un-handled element read from the .osm.pbf file (i.e. file header). */
|
|
record Other(
|
|
@Override long id,
|
|
@Override Map<String, Object> tags
|
|
) implements OsmElement {
|
|
|
|
@Override
|
|
public int cost() {
|
|
return 1 + tags.size();
|
|
}
|
|
}
|
|
|
|
/** A point on the earth's surface. */
|
|
final class Node implements OsmElement {
|
|
|
|
private static final long MISSING_LOCATION = Long.MIN_VALUE;
|
|
private final long id;
|
|
private final Map<String, Object> tags;
|
|
private final double lat;
|
|
private final double lon;
|
|
// bailed out of a record to make encodedLocation lazy since it is fairly expensive to compute
|
|
private long encodedLocation = MISSING_LOCATION;
|
|
|
|
public Node(
|
|
long id,
|
|
Map<String, Object> tags,
|
|
double lat,
|
|
double lon
|
|
) {
|
|
this.id = id;
|
|
this.tags = tags;
|
|
this.lat = lat;
|
|
this.lon = lon;
|
|
}
|
|
|
|
public Node(long id, double lat, double lon) {
|
|
this(id, new HashMap<>(), lat, lon);
|
|
}
|
|
|
|
@Override
|
|
public long id() {
|
|
return id;
|
|
}
|
|
|
|
@Override
|
|
public Map<String, Object> tags() {
|
|
return tags;
|
|
}
|
|
|
|
public double lat() {
|
|
return lat;
|
|
}
|
|
|
|
public double lon() {
|
|
return lon;
|
|
}
|
|
|
|
public long encodedLocation() {
|
|
if (encodedLocation == MISSING_LOCATION) {
|
|
encodedLocation = GeoUtils.encodeFlatLocation(lon, lat);
|
|
}
|
|
return encodedLocation;
|
|
}
|
|
|
|
@Override
|
|
public int cost() {
|
|
return 1 + tags.size();
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object obj) {
|
|
if (obj == this) {
|
|
return true;
|
|
}
|
|
if (obj == null || obj.getClass() != this.getClass()) {
|
|
return false;
|
|
}
|
|
var that = (Node) obj;
|
|
return this.id == that.id &&
|
|
Objects.equals(this.tags, that.tags) &&
|
|
Double.doubleToLongBits(this.lat) == Double.doubleToLongBits(that.lat) &&
|
|
Double.doubleToLongBits(this.lon) == Double.doubleToLongBits(that.lon);
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return Objects.hash(id, tags, lat, lon);
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "Node[" +
|
|
"id=" + id + ", " +
|
|
"tags=" + tags + ", " +
|
|
"lat=" + lat + ", " +
|
|
"lon=" + lon + ']';
|
|
}
|
|
|
|
}
|
|
|
|
/** An ordered list of 2-2,000 nodes that define a polyline. */
|
|
record Way(
|
|
@Override long id,
|
|
@Override Map<String, Object> tags,
|
|
LongArrayList nodes
|
|
) implements OsmElement {
|
|
|
|
public Way(long id) {
|
|
this(id, new HashMap<>(), new LongArrayList(5));
|
|
}
|
|
|
|
@Override
|
|
public int cost() {
|
|
return 1 + tags.size() + nodes.size();
|
|
}
|
|
}
|
|
|
|
/** An ordered list of nodes, ways, and other relations. */
|
|
record Relation(
|
|
@Override long id,
|
|
@Override Map<String, Object> tags,
|
|
List<Member> members
|
|
) implements OsmElement {
|
|
|
|
public Relation(long id) {
|
|
this(id, new HashMap<>(), new ArrayList<>());
|
|
}
|
|
|
|
public Relation {
|
|
if (members == null) {
|
|
members = Collections.emptyList();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int cost() {
|
|
return 1 + tags.size() + members.size() * 3;
|
|
}
|
|
|
|
/**
|
|
* A node, way, or relation contained in a relation with an optional "role" to clarify the purpose of each member.
|
|
*/
|
|
public record Member(
|
|
Type type,
|
|
long ref,
|
|
String role
|
|
) {}
|
|
}
|
|
}
|