diff --git a/htroot/yacysearch.java b/htroot/yacysearch.java index 6c41fef75..182030eea 100644 --- a/htroot/yacysearch.java +++ b/htroot/yacysearch.java @@ -55,7 +55,7 @@ import net.yacy.document.Condenser; import net.yacy.document.Document; import net.yacy.document.LibraryProvider; import net.yacy.document.Parser; -import net.yacy.document.geolocalization.Location; +import net.yacy.document.geolocalization.GeoLocation; import net.yacy.kelondro.data.meta.DigestURI; import net.yacy.kelondro.data.meta.URIMetadataRow; import net.yacy.kelondro.data.word.Word; @@ -909,12 +909,12 @@ public class yacysearch { } // find geographic info - final SortedSet coordinates = LibraryProvider.geoLoc.find(originalquerystring, false); + final SortedSet coordinates = LibraryProvider.geoLoc.find(originalquerystring, false); if ( coordinates == null || coordinates.isEmpty() || startRecord > 0 ) { prop.put("geoinfo", "0"); } else { int i = 0; - for ( final Location c : coordinates ) { + for ( final GeoLocation c : coordinates ) { prop.put("geoinfo_loc_" + i + "_lon", Math.round(c.lon() * 10000.0f) / 10000.0f); prop.put("geoinfo_loc_" + i + "_lat", Math.round(c.lat() * 10000.0f) / 10000.0f); prop.put("geoinfo_loc_" + i + "_name", c.getName()); diff --git a/htroot/yacysearch_location.java b/htroot/yacysearch_location.java index 27bc0618f..68b3ac080 100644 --- a/htroot/yacysearch_location.java +++ b/htroot/yacysearch_location.java @@ -28,7 +28,7 @@ import net.yacy.cora.protocol.HeaderFramework; import net.yacy.cora.protocol.RequestHeader; import net.yacy.cora.services.federated.opensearch.SRURSSConnector; import net.yacy.document.LibraryProvider; -import net.yacy.document.geolocalization.Location; +import net.yacy.document.geolocalization.GeoLocation; import net.yacy.search.Switchboard; import net.yacy.search.SwitchboardConstants; import de.anomic.server.serverCore; @@ -67,11 +67,11 @@ public class yacysearch_location { int placemarkCounter = 0; if (query.length() > 0 && search_query) { - final Set locations = LibraryProvider.geoLoc.find(query, true); + final Set locations = LibraryProvider.geoLoc.find(query, true); for (final String qp: query.split(" ")) { locations.addAll(LibraryProvider.geoLoc.find(qp, true)); } - for (final Location location: locations) { + for (final GeoLocation location: locations) { // write for all locations a point to this message prop.put("kml_placemark_" + placemarkCounter + "_location", location.getName()); prop.put("kml_placemark_" + placemarkCounter + "_name", location.getName()); diff --git a/source/net/yacy/document/geolocalization/Coordinates.java b/source/net/yacy/document/geolocalization/Coordinates.java deleted file mode 100644 index 06fddbd49..000000000 --- a/source/net/yacy/document/geolocalization/Coordinates.java +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Coordinates.java - * Copyright 2009 by Michael Peter Christen; mc@yacy.net, Frankfurt a. M., Germany - * first published 04.10.2009 on http://yacy.net - * - * This file is part of YaCy Content Integration - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program in the file lgpl21.txt - * If not, see . - */ - -package net.yacy.document.geolocalization; - -public class Coordinates { - - private static final double tenmeter = 90.0d / 1.0e6d; - - private final double lon, lat; - - public Coordinates(double lon, double lat) { - this.lon = lon; - this.lat = lat; - } - - public double lon() { - return this.lon; - } - - public double lat() { - return this.lat; - } - - private static final double bits30 = new Double(1L << 30).doubleValue(); // this is about one billion (US) - private static final double upscale = bits30 / 360.0; - - private static final int coord2int(double coord) { - return (int) ((180.0 - coord) * upscale); - } - - /** - * compute the hash code of a coordinate - * this produces identical hash codes for locations that are close to each other - */ - public int hashCode() { - return coord2int(this.lon) + (coord2int(this.lat) >> 15); - } - - /** - * equality test that is needed to use the class inside HashMap/HashSet - */ - public boolean equals(final Object o) { - if (!(o instanceof Coordinates)) return false; - Coordinates oo = (Coordinates) o; - if (this.lon == oo.lon && this.lat == oo.lat) return true; - // we access fuzzy values that are considered as equal if they are close to each other - return Math.abs(this.lon - oo.lon) < tenmeter && Math.abs(this.lat - oo.lat) < tenmeter; - } - - public String toString() { - return "[" + this.lon + "," + this.lat + "]"; - } -} diff --git a/source/net/yacy/document/geolocalization/Location.java b/source/net/yacy/document/geolocalization/GeoLocation.java similarity index 75% rename from source/net/yacy/document/geolocalization/Location.java rename to source/net/yacy/document/geolocalization/GeoLocation.java index 41a6e398c..94c91d73a 100644 --- a/source/net/yacy/document/geolocalization/Location.java +++ b/source/net/yacy/document/geolocalization/GeoLocation.java @@ -1,90 +1,93 @@ -/** - * Location.java - * Copyright 2009 by Michael Peter Christen; mc@yacy.net, Frankfurt a. M., Germany - * first published 08.10.2009 on http://yacy.net - * - * This file is part of YaCy Content Integration - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program in the file lgpl21.txt - * If not, see . - */ - -package net.yacy.document.geolocalization; - -import java.util.Comparator; - - -public class Location extends Coordinates implements Comparable, Comparator { - - private String name; - private int population; - - public Location(float lon, float lat) { - super(lon, lat); - this.name = null; - this.population = 0; - } - - public Location(float lon, float lat, String name) { - super(lon, lat); - this.name = name; - } - - public void setName(String name) { - this.name = name; - } - - public String getName() { - return this.name; - } - - public void setPopulation(int population) { - this.population = population; - } - - public int getPopulation() { - return this.population; - } - - public boolean equals(Object loc) { - if (!(loc instanceof Location)) return false; - if (this.name == null || ((Location) loc).name == null) return super.equals(loc); - return super.equals(loc) && this.name.toLowerCase().equals(((Location) loc).name.toLowerCase()); - } - - /** - * comparator that is needed to use the object inside TreeMap/TreeSet - * a Location is smaller than another if it has a _greater_ population - * this order is used to get sorted lists of locations where the first elements - * have the greatest population - */ - public int compareTo(Location o) { - if (this.equals(o)) return 0; - long s = (ph(this.getPopulation()) << 30) + this.hashCode(); - long t = (ph(o.getPopulation()) << 30) + o.hashCode(); - if (s > t) return -1; - if (s < t) return 1; - return 0; - } - - private long ph(int population) { - if (population > 10000) population -= 10000; - return (long) population; - } - - public int compare(Location o1, Location o2) { - return o1.compareTo(o2); - } - -} +/** + * GeoLocation + * Copyright 2009 by Michael Peter Christen; mc@yacy.net, Frankfurt a. M., Germany + * first published 08.10.2009 on http://yacy.net + * + * This file is part of YaCy Content Integration + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program in the file lgpl21.txt + * If not, see . + */ + +package net.yacy.document.geolocalization; + +import java.util.Comparator; + + +public class GeoLocation extends GeoPoint implements Comparable, Comparator { + + private String name; + private int population; + + public GeoLocation(double lat, double lon) { + super(lat, lon); + this.name = null; + this.population = 0; + } + + public GeoLocation(double lat, double lon, String name) { + super(lat, lon); + this.name = name; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + public void setPopulation(int population) { + this.population = population; + } + + public int getPopulation() { + return this.population; + } + + @Override + public boolean equals(Object loc) { + if (!(loc instanceof GeoLocation)) return false; + if (this.name == null || ((GeoLocation) loc).name == null) return super.equals(loc); + return super.equals(loc) && this.name.toLowerCase().equals(((GeoLocation) loc).name.toLowerCase()); + } + + /** + * comparator that is needed to use the object inside TreeMap/TreeSet + * a Location is smaller than another if it has a _greater_ population + * this order is used to get sorted lists of locations where the first elements + * have the greatest population + */ + @Override + public int compareTo(GeoLocation o) { + if (this.equals(o)) return 0; + long s = (ph(this.getPopulation()) << 30) + this.hashCode(); + long t = (ph(o.getPopulation()) << 30) + o.hashCode(); + if (s > t) return -1; + if (s < t) return 1; + return 0; + } + + private long ph(int population) { + if (population > 10000) population -= 10000; + return population; + } + + @Override + public int compare(GeoLocation o1, GeoLocation o2) { + return o1.compareTo(o2); + } + +} diff --git a/source/net/yacy/document/geolocalization/GeoPoint.java b/source/net/yacy/document/geolocalization/GeoPoint.java new file mode 100644 index 000000000..c948c44d1 --- /dev/null +++ b/source/net/yacy/document/geolocalization/GeoPoint.java @@ -0,0 +1,91 @@ +/** + * GeoPoint + * Copyright 2009 by Michael Peter Christen; mc@yacy.net, Frankfurt a. M., Germany + * first published 08.10.2009 on http://yacy.net + * + * This file is part of YaCy Content Integration + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program in the file lgpl21.txt + * If not, see . + */ + +package net.yacy.document.geolocalization; + + +public class GeoPoint { + + public static final double meter = 90.0d / 1.0e7d; // this is actually the definition of 'meter': 10 million meter shall be the distance from the equator to the pole + + private final long latlon; // using one variable for the coordinate pair saves some space + + public GeoPoint(double lat, double lon) { + this.latlon = (((long) coord2int(lat)) << 32) | (coord2int(lon)); + } + + + public GeoPoint(int lat, int lon) { + this.latlon = (((long) coord2int(lat / 1e6d)) << 32) | (coord2int(lon / 1e6d)); + } + + public double lon() { + return int2coord((int) (this.latlon & (Integer.MAX_VALUE))); + } + + public double lat() { + return int2coord((int) (this.latlon >>> 32)); + } + + private static final double maxint = new Double(Integer.MAX_VALUE).doubleValue(); + private static final double upscale = maxint / 360.0; + + private static final int coord2int(double coord) { + return (int) ((coord + 180.0) * upscale); + } + + private static final double int2coord(int z) { + return (z / upscale) - 180.0; + } + + /** + * compute the hash code of a coordinate + * this produces identical hash codes for locations that are close to each other + */ + @Override + public int hashCode() { + return (int) ((this.latlon & Integer.MAX_VALUE) >> 1) + (int) (this.latlon >> 33); + } + + /** + * equality test that is needed to use the class inside HashMap/HashSet + */ + @Override + public boolean equals(final Object o) { + if (!(o instanceof GeoPoint)) return false; + GeoPoint oo = (GeoPoint) o; + return (this.latlon == oo.latlon); + } + + @Override + public String toString() { + return "[" + this.lat() + "," + this.lon() + "]"; + } + + public static void main(String[] args) { + double lat = 13.419444d; + double lon = 52.548611d; + GeoPoint c = new GeoPoint(lat, lon); + System.out.println(c.toString() + " #" + c.hashCode()); + System.out.println("error: lat: " + (Math.abs(c.lat() - lat) / meter) + " meter; lon: " + (Math.abs(c.lon() - lon) / meter) + " meter"); + } +} diff --git a/source/net/yacy/document/geolocalization/GeonamesLocalization.java b/source/net/yacy/document/geolocalization/GeonamesLocalization.java index f23ea4f54..2f6225069 100644 --- a/source/net/yacy/document/geolocalization/GeonamesLocalization.java +++ b/source/net/yacy/document/geolocalization/GeonamesLocalization.java @@ -69,7 +69,7 @@ public class GeonamesLocalization implements Localization modification date : date of last modification in yyyy-MM-dd format */ - private final Map id2loc; + private final Map id2loc; private final TreeMap> name2ids; private final File file; @@ -77,7 +77,7 @@ public class GeonamesLocalization implements Localization // this is a processing of the cities1000.zip file from http://download.geonames.org/export/dump/ this.file = file; - this.id2loc = new HashMap(); + this.id2loc = new HashMap(); this.name2ids = new TreeMap>(StringBuilderComparator.CASE_INSENSITIVE_ORDER); @@ -112,8 +112,8 @@ public class GeonamesLocalization implements Localization for ( final String s : fields[3].split(",") ) { locnames.add(new StringBuilder(s)); } - final Location c = - new Location(Float.parseFloat(fields[5]), Float.parseFloat(fields[4]), fields[1]); + final GeoLocation c = + new GeoLocation(Float.parseFloat(fields[4]), Float.parseFloat(fields[5]), fields[1]); c.setPopulation((int) Long.parseLong(fields[14])); this.id2loc.put(id, c); for ( final StringBuilder name : locnames ) { @@ -136,7 +136,7 @@ public class GeonamesLocalization implements Localization } @Override - public TreeSet find(final String anyname, final boolean locationexact) { + public TreeSet find(final String anyname, final boolean locationexact) { final Set r = new HashSet(); List c; final StringBuilder an = new StringBuilder(anyname); @@ -155,9 +155,9 @@ public class GeonamesLocalization implements Localization } } } - final TreeSet a = new TreeSet(); + final TreeSet a = new TreeSet(); for ( final Integer e : r ) { - final Location w = this.id2loc.get(e); + final GeoLocation w = this.id2loc.get(e); if ( w != null ) { a.add(w); } diff --git a/source/net/yacy/document/geolocalization/Localization.java b/source/net/yacy/document/geolocalization/Localization.java index 3008c4d70..4b7b87add 100644 --- a/source/net/yacy/document/geolocalization/Localization.java +++ b/source/net/yacy/document/geolocalization/Localization.java @@ -45,7 +45,7 @@ public interface Localization { * @param locationexact - if true, then only exact matched with the location are returned. if false also partially matching names * @return a set of locations, ordered by population (if this information is given) */ - public TreeSet find(String anyname, boolean locationexact); + public TreeSet find(String anyname, boolean locationexact); /** * produce a set of location names diff --git a/source/net/yacy/document/geolocalization/OpenGeoDBLocalization.java b/source/net/yacy/document/geolocalization/OpenGeoDBLocalization.java index f0f891e8e..e02858a0e 100644 --- a/source/net/yacy/document/geolocalization/OpenGeoDBLocalization.java +++ b/source/net/yacy/document/geolocalization/OpenGeoDBLocalization.java @@ -53,7 +53,7 @@ public class OpenGeoDBLocalization implements Localization { private final Map locTypeHash2locType; - private final Map id2loc; + private final Map id2loc; private final Map id2locTypeHash; private final TreeMap> name2ids; private final TreeMap> kfz2ids; @@ -65,7 +65,7 @@ public class OpenGeoDBLocalization implements Localization this.file = file; this.locTypeHash2locType = new HashMap(); - this.id2loc = new HashMap(); + this.id2loc = new HashMap(); this.id2locTypeHash = new HashMap(); this.name2ids = new TreeMap>(StringBuilderComparator.CASE_INSENSITIVE_ORDER); @@ -112,7 +112,7 @@ public class OpenGeoDBLocalization implements Localization lat = Float.parseFloat(v[2]); lon = Float.parseFloat(v[3]); } - this.id2loc.put(Integer.parseInt(v[0]), new Location(lon, lat)); + this.id2loc.put(Integer.parseInt(v[0]), new GeoLocation(lat, lon)); } if ( line.startsWith("geodb_textdata ") ) { line = line.substring(15 + 7); @@ -126,7 +126,7 @@ public class OpenGeoDBLocalization implements Localization } l.add(id); this.name2ids.put(new StringBuilder(h), l); - final Location loc = this.id2loc.get(id); + final GeoLocation loc = this.id2loc.get(id); if ( loc != null ) { loc.setName(h); } @@ -200,7 +200,7 @@ public class OpenGeoDBLocalization implements Localization * @return */ @Override - public TreeSet find(final String anyname, final boolean locationexact) { + public TreeSet find(final String anyname, final boolean locationexact) { final HashSet r = new HashSet(); List c; final StringBuilder an = new StringBuilder(anyname); @@ -231,9 +231,9 @@ public class OpenGeoDBLocalization implements Localization r.add(i); } } - final TreeSet a = new TreeSet(); + final TreeSet a = new TreeSet(); for ( final Integer e : r ) { - final Location w = this.id2loc.get(e); + final GeoLocation w = this.id2loc.get(e); if ( w != null ) { a.add(w); } diff --git a/source/net/yacy/document/geolocalization/OverarchingLocalization.java b/source/net/yacy/document/geolocalization/OverarchingLocalization.java index 93a8183ba..26fded0ba 100644 --- a/source/net/yacy/document/geolocalization/OverarchingLocalization.java +++ b/source/net/yacy/document/geolocalization/OverarchingLocalization.java @@ -76,8 +76,8 @@ public class OverarchingLocalization implements Localization { * @return a set of locations, ordered by population (if this information is given) */ @Override - public TreeSet find(final String anyname, final boolean locationexact) { - final TreeSet locations = new TreeSet(); + public TreeSet find(final String anyname, final boolean locationexact) { + final TreeSet locations = new TreeSet(); for (final Localization service: this.services.values()) { locations.addAll(service.find(anyname, locationexact)); }