2016-12-02 1 views
1

J'essaye de stocker un objet GeoJson Polygon à Mongodb en utilisant Morphia. S'il vous plaît noter que les coordonnées de GeoJson Polygon doivent être tableau de profondeur à 3 niveaux comme ci-dessous.Impossible de stocker l'objet GeoJson Polygon dans Mongodb en utilisant Morphia avec Java

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

Voici ma classe Entity.

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); 

     } 
    } 

Lorsque je le stocke, Morphia me donne l'exception suivante.

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 

Répondre

1

Avait le même problème et est arrivé à la conclusion suivante. Au lieu d'utiliser votre classe personnalisée, vous devriez utiliser ce que Morphia vous fournit. Principalement, vous pouvez simplement créer votre polygone comme ceci:

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(); 
    } 
} 

Vous pouvez créer votre index de 2dsphere et d'effectuer des requêtes recouper $ aucun problème.

+0

J'ai fini par créer une hashmap comme 'private HashMap loc = new HashMap ()' et ensuite mettre la totalité de 'ArrayList > coordonnées' comme valeur dans la carte. Mais c'est une solution de contournement. On dirait un bug dans Morphia? – Arjit

+0

Cela ne fonctionnera pas, car le format GeoJSON pour le polygone est {"type": "Point", "coordonnées": [....]} et avec votre solution vous obtenez {"Point": [... ]}. Pouvez-vous donner un exemple d'enregistrement d'un polygone en db avec votre solution? Quoi qu'il en soit, ce n'est pas un bug dans Morphia mais à mon avis la documentation n'est pas suffisante. Nous espérons pouvoir fournir suffisamment d'informations pour d'autres personnes qui trébuchent sur ce problème. – RafalManka

+0

dans le HashMap que j'ai mentionné. Je mets deux paires de valeurs clés. 'loc.put (" type "," Polygon "); loc.put ("coordonnées", coordonnées); ' ici coordonnées est une collection de points de type' ArrayList > ' – Arjit