我有这样的数据:
23.3445556 72.4535455 0.23434
23.3645556 72.4235455 0.53434
23.3245556 72.4635455 0.21434
23.3645556 72.2535455 0.25434
我想这样HashMap
:
HashMap<23.34444,72.23455,0.2345566> demo = new HashMap()
此处23.34444,72.23455
是关键,0.2345566
是值。
这是因为我想像这样遍历HashMap
:
if(demo.latitude < 21.45454545 && demo.longitude > 72.3455)
//get the value from hashMap
long lat repn在地图上的特定像素,每个像素都有相同的值,我想从特定区域获得avg值假设x y和像素将高达100万
答案 0 :(得分:2)
您可以使用Point类开始。
https://docs.oracle.com/javase/7/docs/api/java/awt/Point.html
int xE6 = x*1e6
int yE6 = y*1e6
new Point(xE6, yE6)
但由于这是特定的,并且滥用了这个课程,你最终可能会想要创建自己的课程。
public final class LatLon {
private double lat;
private double lon;
public LatLon(double lat, double lon) {
this.lat = lat;
this.lon = lon;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
LatLon latLon = (LatLon) o;
if (Double.compare(latLon.lat, lat) != 0) return false;
return Double.compare(latLon.lon, lon) == 0;
}
@Override
public int hashCode() {
int result;
long temp;
temp = Double.doubleToLongBits(lat);
result = (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(lon);
result = 31 * result + (int) (temp ^ (temp >>> 32));
return result;
}
public double getLat() {
return lat;
}
public void setLat(double lat) {
this.lat = lat;
}
public double getLon() {
return lon;
}
public void setLon(double lon) {
this.lon = lon;
}
}
(使用IntelliJ自动生成)
这可以像
一样使用public static void main(String[] args) {
HashMap<LatLon, Double> demo = new HashMap<LatLon, Double>();
demo.put(new LatLon(23.3445556,72.4535455), 0.23434);
demo.put(new LatLon(23.3645556,72.4235455), 0.53434);
demo.put(new LatLon(23.3245556,72.4635455), 0.21434);
demo.put(new LatLon(23.3645556,72.2535455), 0.25434);
System.out.println(demo.get(new LatLon(23.3645556,72.2535455))); //0.25434
}
使用此类的问题在于它使用了双精度型。您需要某种精度,由小数位置给出。
双打有奇怪的数学,并且可以给你准确性错误,所以我衷心建议使用专为地理坐标设计的库。
特别是
if(demo.latitude&lt; 21.45454545&amp;&amp; demo.longitude&gt; 72.3455)
如果最终遇到性能问题,这种检查最好通过某种专门构建的集合来处理边界检查和坐标。
答案 1 :(得分:1)
如果它是您正在创建的演示,我建议您创建一个枚举类,其中每个坐标都要展示为单独的枚举对象或HashMap的键。
如果这不适合你,我会创建一个&#34; Coordinates&#34;在那里分类并存储密钥。你必须覆盖hashcode和equals方法,否则它可能不会像你想要的那样。
实施例
step. 5
答案 2 :(得分:1)
我认为你正在以错误的方式解决问题。使用HashMap
将无法正常使用大于或小于比较。如果您有2个与您的比较匹配的latlong键,会发生什么?你选择什么价值?
我可能会像这样解决你的问题:
首先,创建一个包含&#34;键&#34;的类。价值和你的价值&#34;值
public class GeoValue {
double lat;
double lon;
double value;
}
然后,将比较方法添加到类
public boolean lessThanLatGreaterThanLon(double lat, double lon) {
return lat < this.lat && lon > this.lon;
}
将所有这些创建的对象添加到Set
类型集合中。如果您使用HashSet
,请确保同时覆盖.equals()
课程的.hashCode
和GeoValue
方法。
要查找所需的值,您可以使用filter
方法(如果您使用的是Java8或示例)
final double lat = 3.5D;
final double lon = 4.5D;
Set<GeoValue> matchingValues = geoValues.stream()
.filter(geo -> geo.lessThanLatGreaterThanLon(lat, lon))
.collect(Collectors.toSet());
你准备好了。
答案 3 :(得分:1)
HashMap
将无法满足您的需求,因为它不适用于范围查询,即为我提供其密钥最接近12.0
的条目,或者为我提供密钥之间的所有条目{ {1}}和10.0
。
有效地处理地理点的特殊用途结构,即R-tree或R* tree。
这类树需要您根据类似地理位置的结构(通常是纬度/经度对)索引数据,但它们也允许根据地理形状对数据进行索引。
创建要用作键的lat / lon对对象(如其他答案中所建议)仅在使用存储空间数据并将其编入索引的专用结构时才有用。否则,具有此类对将是毫无意义的,因为您将无法搜索在附近给定位置的点,或位于给定矩形内的点等。
现在,如果您不想使用R-tree的方式,并且可以使用非常有限的空间查询,则可能需要考虑使用以下结构:
20.0
这是TreeMap<Double, TreeMap<Double, Double>> demo = new TreeMap<>();
的{{1}},其目的是将纬度作为外部地图的关键,将经度作为内部地图的关键。 因此,您必须首先按纬度搜索,然后按经度搜索 。
如果你没问题,你可以利用一些very useful methods of TreeMap
,例如TreeMap
,TreeMap
和headMap
,来命名最相关的。{ / p>
例如,如果要查找由其左上角tailMap
及其右下角subMap
确定的矩形内的所有点,可以按以下方式执行:
[-10.0, -10.0]
即使是100万分,性能也是合理的,但不是最好的,因为[10.0, 10.0]
是基于红/黑树的通用// Get all points with latitude between -10.0 and 10.0
SortedMap<Double, TreeMap<Double, Double>> byLat = demo.subMap(-10.0, 10.0);
// Now print points from byLat submap with longitude between -10.0 and 10.0
byLat.entrySet().stream()
.map(e -> e.getValue().subMap(-10.0, 10.0))
.forEach(System.out::println);
实现,TreeMap
时间复杂度。
另一方面,如果您愿意安装某些软件,我建议您将Elasticsearch与Geolocation一起使用。它具有geo-point和geo-shaped专用数据类型,可以让您的生活更轻松。这个搜索引擎具有出色的性能,可以水平扩展到数千个节点,因此内存,查找时间等都不会成为问题。
答案 4 :(得分:0)
您可以根据经度,纬度生成哈希码,然后使用该哈希码作为保存值的键。这样它将更简单,而不是直接使用它们或将它们转换为一个点,因为在以后的某个时间点没有使用该点。
答案 5 :(得分:0)
您还可以使用Point2D类作为java.awt的一部分。你将需要扩展它并制作一个具体的类,但它会给你所有内置的equals / hashcode等。对于整数坐标,你可以使用相同库中的Point类(不需要扩展)