Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中将经纬度作为HashMap的键_Java_Hashmap - Fatal编程技术网

在Java中将经纬度作为HashMap的键

在Java中将经纬度作为HashMap的键,java,hashmap,Java,Hashmap,我有这样的数据: 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() if(demo.latitude < 21.45454545 &&

我有这样的数据:

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()
if(demo.latitude < 21.45454545 && demo.longitude > 72.3455)
    //get the value from hashMap   
长lat代表地图上的特定像素,每个像素都有相同的值,我想从特定区域获得平均值,假设x和y,像素将高达100万

  • 我想知道这是否是一个好方法,因为它每天都会受到数百万次的点击

如果是您正在创建的演示,我建议您创建一个枚举类,其中每个坐标都要显示为单独的枚举对象或哈希映射的键

如果这对您不起作用,我将创建一个“坐标”类并将键存储在那里。不过,您必须重写hashcode和equals方法,否则它的行为可能与您希望的不一样

范例

公共类坐标{
双纬度,经度;
}
...
HashMap demo=新建HashMap();/*注:坐标对象是关键点。因此,首先必须创建一个坐标对象类,输入纬度和经度值,然后输入HashMap作为键*/

您可以使用Point类开始

但是,由于这是特定于awt的,并且是对类的滥用,因此您可能最终想要创建自己的类

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
}
publicstaticvoidmain(字符串[]args){
HashMap demo=新建HashMap();
演示放置(新LatLon(23.3445556,72.4535455),0.23434);
演示放置(新LatLon(23.3645556,72.4235455),0.53434);
演示放置(新拉特隆(23.32455556,72.4635455),0.21434);
演示放置(新拉特伦(23.3645556,72.2535455),0.25434);
System.out.println(demo.get(new-LatLon(23.3645556,72.2535455));/0.25434
}
按原样使用这个类的问题是它使用了double。您需要某种精度,由十进制位置给出

Double具有奇怪的数学特性,并且会给您带来精度误差,因此我衷心建议您使用专为地理坐标设计的库

特别是考虑到

如果(演示latitude72.3455)


如果最终遇到性能问题,最好使用某种专门构建的集合来处理边界检查和协调

您可以基于经度、纬度生成哈希代码,然后将该哈希代码用作保存值的键。这样做会更简单,而不是直接使用它们或将它们转换为一个点,因为在以后的时间点上没有使用该点。

我认为您处理问题的方式是错误的。使用
HashMap
将无法正确处理大于或小于的比较。如果您有两个匹配比较的latlong键,会发生什么?你选择什么价值

我可能会这样解决你的问题:

HashMap<23.34444,72.23455,0.2345566> demo = new HashMap()
if(demo.latitude < 21.45454545 && demo.longitude > 72.3455)
    //get the value from hashMap   
首先,创建一个包含“key”值和“value”值的类

然后,向类添加一个比较方法

public boolean lessThanLatGreaterThanLon(double lat, double lon) {
  return lat < this.lat && lon > this.lon;
}

您可以开始了。

HashMap
不会满足您的需要,因为它不适用于范围查询,即,给我键最接近
12.0
的条目,或者给我键
10.0
20.0
之间的所有条目

有一些特殊用途的结构可以有效地处理地理点,即或

这类树要求您基于类似于地理点的结构(通常是纬度/经度对)对数据进行索引,尽管它们也允许基于地理形状对数据进行索引

只有当您使用存储和索引空间数据的专用结构时,创建用作密钥的lat/lon对对象(如其他答案中所建议的)才有用。否则,拥有这样的对将毫无意义,因为您将无法搜索给定位置附近的点,或位于给定矩形内的点等


现在,如果您不想去R-树的方式,并且可以使用非常有限的空间查询,那么您可能需要考虑使用以下结构:

TreeMap<Double, TreeMap<Double, Double>> demo = new TreeMap<>();
即使对于100万个点,性能也是合理的,尽管不是最好的,因为
TreeMap
是基于红/黑树的通用
Map
实现,具有
O(logn)
时间复杂度



另一方面,如果您愿意安装一些软件,我建议您使用。它有许多特殊的数据类型,可以让你的生活更轻松。此搜索引擎具有出色的性能,可水平扩展到数千个节点,因此内存、查找时间等不会成为问题。

您还可以使用java.awt中提供的Point2D类。您需要对其进行扩展并生成一个具体的类,但它将为您提供equals/hashcode等所有内置代码。对于整数坐标,可以使用同一库中的Point类(无需扩展)

将这个:23.34444,72.23455转换为点类听起来像是想要一个表示lat/long值的类……请注意,HashMap是为相等比较而设计的,而不是您在最后显示的那种比较。我认为您不能按照您想要的方式使用
HashMap
。如果您有两个键,每个键都与
if
条件匹配,会发生什么情况?您选择哪个值?AWT点用于表示屏幕上的坐标,以像素为单位。因此,坐标是
int
,而不是lat/long所需的
double
。另外,
x*10^6
可能没有做您认为它做的事情。我将它改为double,主要是因为我太懒了,无法创建一个基于Int的答案来转换这个问题的intE6 location格式。该类不完整,无法在hashMap中使用。您所说的“类不完整”是什么意思?他的意思是你还需要一个
hashCode
方法,这样类才能正确地作为
HashMap
键工作。他们提到它需要一个等式和hashCode方法,b
final double lat = 3.5D;
final double lon = 4.5D;
Set<GeoValue> matchingValues = geoValues.stream()
    .filter(geo -> geo.lessThanLatGreaterThanLon(lat, lon))
    .collect(Collectors.toSet());
TreeMap<Double, TreeMap<Double, Double>> demo = new TreeMap<>();
// 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);