2016-12-02 98 views
1

我正在尝试使用Morphia存储一个GeoJson多边形对象到Mongodb。请注意,GeoJson多边形坐标必须是3级深度数组,如下所示。无法使用Morphia和Java在Mongodb中存储GeoJson多边形对象

{ 
    type: "Polygon", 
    coordinates: [ [ [ 0 , 0 ] , [ 3 , 6 ] , [ 6 , 1 ] , [ 0 , 0 ] ] ] 
} 

以下是我的实体类。

static class Loc { 
     private final String type = "Polygon"; 
     private ArrayList<ArrayList<Double[]>> coordinates = new ArrayList<ArrayList<Double[]>>(); 
     public ArrayList<ArrayList<Double[]>> getCoordinates() { 
      return coordinates; 
     } 
     public void setCoordinates(ArrayList<Double[]> coordinates) { 
      this.coordinates.add(coordinates); 

     } 
    } 

当我存储它时,Morphia给了我下面的例外。

Exception in thread "main" org.mongodb.morphia.mapping.MappingException: Error mapping field:com.utils.JavaUtils$Poly.loc 
    at org.mongodb.morphia.mapping.Mapper.toDBObject(Mapper.java:983) 
    at org.mongodb.morphia.mapping.Mapper.toDBObject(Mapper.java:593) 
    at org.mongodb.morphia.DatastoreImpl.entityToDBObj(DatastoreImpl.java:1359) 
    at org.mongodb.morphia.DatastoreImpl.save(DatastoreImpl.java:1279) 
    at org.mongodb.morphia.DatastoreImpl.save(DatastoreImpl.java:775) 
    at org.mongodb.morphia.DatastoreImpl.save(DatastoreImpl.java:758) 
    at com.utils.JavaUtils.polygonizeAndSave(JavaUtils.java:105) 
    at com.examples.MainExample$$anonfun$main$4.apply(MainExample.scala:71) 
    at com.examples.MainExample$$anonfun$main$4.apply(MainExample.scala:71) 
    at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59) 
    at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:48) 
    at com.examples.MainExample$.main(MainExample.scala:71) 
    at com.examples.MainExample.main(MainExample.scala) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:736) 
    at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:185) 
    at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:210) 
    at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:124) 
    at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala) 


    Caused by: org.mongodb.morphia.mapping.MappingException: Error mapping field:com.utils.JavaUtils$Poly$Loc.coordinates 
    at org.mongodb.morphia.mapping.Mapper.toDBObject(Mapper.java:983) 
    at org.mongodb.morphia.mapping.Mapper.toDBObject(Mapper.java:593) 
    at org.mongodb.morphia.mapping.EmbeddedMapper.toDBObject(EmbeddedMapper.java:98) 
    at org.mongodb.morphia.mapping.Mapper.writeMappedField(Mapper.java:875) 
    at org.mongodb.morphia.mapping.Mapper.toDBObject(Mapper.java:981) 
    ... 21 more 


    Caused by: java.lang.IllegalArgumentException: BasicBSONList can only work with numeric keys, not: [className] 
    at org.bson.types.BasicBSONList._getInt(BasicBSONList.java:168) 
    at org.bson.types.BasicBSONList._getInt(BasicBSONList.java:160) 
    at org.bson.types.BasicBSONList.removeField(BasicBSONList.java:117) 
    at org.mongodb.morphia.mapping.EmbeddedMapper.writeCollection(EmbeddedMapper.java:243) 
    at org.mongodb.morphia.mapping.EmbeddedMapper.toDBObject(EmbeddedMapper.java:90) 
    at org.mongodb.morphia.mapping.Mapper.writeMappedField(Mapper.java:875) 
    at org.mongodb.morphia.mapping.Mapper.toDBObject(Mapper.java:981) 
    ... 25 more 

回答

1

有同样的确切问题,并得出以下结论。您应该使用Morphia为您提供的内容,而不是使用自定义类。主要是你可以创建你的多边形这样的:

import org.mongodb.morphia.geo.Point; 
import org.mongodb.morphia.geo.Polygon; 
import org.mongodb.morphia.geo.GeoJson; 

public class Main { 
    private static PlaceDAO placeDAO = ...; 

    public static void main(String[] args) {    
     Place place = new Place(); 

     Point point1 = GeoJson.point(0.0, 0.0); 
     Point point2 = GeoJson.point(0.0, 0.1); 
     Point point3 = GeoJson.point(0.1, 0.0); 
     Point point4 = GeoJson.point(0.0, 0.0); 
     Polygon location = GeoJson.polygon(point1, point2, point3, point4); 

     place.setLocation(location); 

     placeDAO.save(place); 
     List<Place> places = shopDAO.find().asList(); 
    } 
} 

您可以创建2dsphere指数和执行$相交查询没有问题。

+0

我最终创建了一个类似'private HashMap loc = new HashMap ()'的散列表,然后将整个'ArrayList >坐标作为一个值放到地图中。但是这是一个解决方法。看起来像Morphia中的一个错误? – Arjit

+0

这不起作用,因为多边形的GeoJSON格式是{“type”:“Point”,“coordinates”:[....]}并且您的解决方案获得{“Point”:[... ]}。你能举一个例子,用你的解决方案将一个多边形保存到db中吗?无论如何,这不是Morphia中的一个错误,但在我看来,文档是不够的。希望我们能够为其他遇到这个问题的人提供足够的信息。我提到的HashMap中的 – RafalManka

+0

。我把两个关键值对。 'loc.put(“type”,“Polygon”); loc.put(“coordinates”,coordinates);' 这里的坐标是一个点类型的集合'ArrayList >' – Arjit