„Spatial4J” változatai közötti eltérés

Innen: GIS Wiki
 
(13 közbenső módosítás ugyanattól a szerkesztőtől nincs mutatva)
1. sor: 1. sor:
A '''Spatial4j''' egy általános térinformatikai, open source Java könyvtár (ASL license). A könyvtár 3 területen ad segítséget: közönséges alakzatok euklideszi és geodéziai modellekhez, távolság és egyéb számítások, alakzatok írása/olvasása '''GeoJSON''' és '''WKT'''(Well Known Text) formátumokból .
+
A '''Spatial4j''' egy általános térinformatikai, open source Java könyvtár ([http://www.apache.org/licenses/LICENSE-2.0.html ASL] license). A könyvtár 3 területen ad segítséget: közönséges alakzatok euklideszi és geodéziai modellekhez, távolság és egyéb számítások, alakzatok írása/olvasása [http://geojson.org/ '''GeoJSON'''] és [https://en.wikipedia.org/wiki/Well-known_text '''WKT'''](Well Known Text) formátumokból .
  
 
== Történet ==
 
== Történet ==
32. sor: 32. sor:
  
  
Habár a konstruktorok használata nincs megtiltva, azok használata általában mégsem ajánlott, kivéve a <code>SpatialContextFactory</code> esetében. Konstruktorok helyett a különböző factory objektumokat használjuk, melyek a ''SpatialContext'' példányokon keresztül érhetőek el.
+
A konstruktorok használata nincs megtiltva, azonban mégsem ajánlott, kivéve a <code>SpatialContextFactory</code> esetében. Konstruktorok helyett a különböző factory objektumokat használjuk, melyek a ''SpatialContext'' példányokon keresztül érhetőek el.
  
 
== Alakzatok ==
 
== Alakzatok ==
42. sor: 42. sor:
 
* terület kiszámítása (néhány alakzatnál ez inkább csak becslés)
 
* terület kiszámítása (néhány alakzatnál ez inkább csak becslés)
 
* tartalmaz-e egy adott pontot
 
* tartalmaz-e egy adott pontot
* milyen kapcsolatban áll egy téglalappal: tartalmazza az adott téglalapot (CONTAINS), benne van-e az adott alakzatban (WITHIN), nincs közös pont(DISJOINT). Az érintésre nincs számítás a Spatial4j-ben
+
* milyen kapcsolatban áll egy téglalappal: tartalmazza az adott téglalapot (CONTAINS), benne van-e az adott alakzatban (WITHIN), nincs közös pont (DISJOINT). Az érintésre nincs számítás a Spatial4j-ben
  
Alakzatok használata: A SpatialContext make metódusaival hozhatunk létre alakzatokat (pl. makePoint, makeRectangle, stb.)
+
A Spatial4J-ben használható alakzatok: Point, Code, Rectangle, LineString, Polygon, ShapeCollection. Alakzatokat a <code>ShapeFactory</code> segítségével tudunk létrehozni:
 +
 
 +
<syntaxhighlight lang="java">
 +
 
 +
JtsSpatialContext ctx= JtsSpatialContext.GEO;
 +
 
 +
Point point = ctx.getShapeFactory().pointXY(10,10);
 +
 
 +
Circle circle = ctx.getShapeFactory().circle(point, 15); // vagy .circle(10,10,0)
 +
 
 +
Rectangle r = ctx.getShapeFactory().rectangle(point1, point2); //vagy .rectangle(0,0,10,10)
 +
 
 +
Shape lineString = ctx.getShapeFactory().lineString()
 +
                .pointXY(0,1)
 +
                .pointXY(2,3)
 +
                .build();
 +
 
 +
Shape shapeCollection = ctx.getShapeFactory().multiShape(Shape.class)
 +
                .add(p)
 +
                .add(circle)
 +
                .build();
 +
 
 +
Shape polygon = globalContext.getShapeFactory().polygon()
 +
                .pointXY(0,0)
 +
                .pointXY(2,3)
 +
                .pointXY(10,5)
 +
                .build();
 +
 
 +
</syntaxhighlight>
 +
 
 +
====Terület és távolság számítás====
  
 
==Alakzatok írása/olvasása szöveges formátumokból==
 
==Alakzatok írása/olvasása szöveges formátumokból==
53. sor: 83. sor:
 
A beolvasott adatokból a megfelelő <code>Shape</code> objektumok állnak elő. Íráskor pedig a különböző alakzatainkat tudjuk adott formátumban kiírni.
 
A beolvasott adatokból a megfelelő <code>Shape</code> objektumok állnak elő. Íráskor pedig a különböző alakzatainkat tudjuk adott formátumban kiírni.
  
=== GeoJSON ===
+
Az olvasást a <code>ShapeReader</code> által adott ''read'' művelettel tudjuk megtenni, aminek vagy egy <code>Obejct</code> vagy egy <code>Reader</code> (java.io.Reader) típusú paramétert vár.
<code>GeoJSONReader</code> objektumot (és általában a <code>ShapeReader</code> objektumokat) kétféleképpen érjük el a ''SpatialContextből''
+
 
 +
 
 +
<code>ShapeReader</code> objektumokat kétféleképpen érjük el a ''SpatialContextből''
  
 
<syntaxhighlight lang="java">
 
<syntaxhighlight lang="java">
61. sor: 93. sor:
 
ShapeReader shapeReader2 = ctx.getFormats().getGeoJsonReader();
 
ShapeReader shapeReader2 = ctx.getFormats().getGeoJsonReader();
 
</syntaxhighlight>
 
</syntaxhighlight>
A ShapeReader
 
  
 +
Illetve ha írni szeretnénk, akkor hasonlóan jutunk egy <code>ShapeWriter</code> objektumhoz:
 +
 +
<syntaxhighlight lang="java">
 +
ShapeWriter shapeWriter1= ctx.getFormats().getWriter(ShapeIO.GeoJSON);
 +
 +
ShapeWriter shapeWriter2 = ctx.getFormats().getGeoJsonWriter();
 +
</syntaxhighlight>
 +
 +
====Példa egy WKT formátumú fájl beolvasására ====
 +
A fájl tartalma például legyen a következő:
 +
<syntaxhighlight lang="wkt">
 +
POINT (19.797752 47.171645)
 +
</syntaxhighlight>
 +
 +
A beolvasás pedig így működik:
 +
<syntaxhighlight lang="java">
 +
 +
try(FileReader reader = new FileReader(path)){
 +
 +
  SpatialContext ctx = SpatialContext.GEO;
 +
  ShapeReader shapeReader = ctx.getFormats().getWktReader();
 +
  Shape shape = shapeReader.read(reader);
 +
  /*
 +
  Ha kiíratjuk, látszik, hogy a beolvasott alakzatunk egy pont:
 +
  System.out.println(shape);
 +
  Pt(x=19.797752,y=47.171645)
 +
  */
 +
}catch (Exception ex){
 +
  //handle
 +
}
 +
 +
</syntaxhighlight>
  
=== WKT ===
+
====Példa egy alakzat kiírására GeoJSONben====
 +
<syntaxhighlight lang="java">
 +
 
 +
SpatialContext ctx = SpatiaContext.GEO;
 +
ShapeWriter shapeWriter = ctx.getFormats().getGeoJsonWriter();
 +
 
 +
Point point = ctx.getShapeFactory().pointXY(18.967123,47.643696);
 +
 
 +
try(FileWriter writer = new FileWriter("path")) {
 +
 
 +
  shapeWriter.write(writer, shape);
 +
 
 +
} catch (IOException e) {
 +
  // handle exception       
 +
}
 +
</syntaxhighlight>
 +
 
 +
Ezek után a fájlunk tartalma a következő kell legyen:
 +
<syntaxhighlight lang="json">
 +
{"type":"Point","coordinates":[18.967123,47.643696]}
 +
</syntaxhighlight>
 +
 
 +
==Geohash==
 +
 
 +
 
 +
<code>GeohashUtils</code> osztály segítségével lehetőségünk van koordináták geohashbe kódolására, valamint geohashből is dekódolhatunk koordinátákat.
 +
 
 +
A geohash lényege, hogy a Földön található koordinátákat egy rövidebb alakba kódolja. Célja, hogy egy olyan karakter sort kapunk, amivel egyértelműen és kényelmesebben hivatkozhatunk a koordinátákra. Bővebben lásd: [https://en.wikipedia.org/wiki/Geohash Geohash Wikipedia]
 +
 
 +
<syntaxhighlight lang="java">
 +
GeohashUtils.encodeLatLon(47.64369627,18.96712353); //u2mrp972wh8q
 +
GeohashUtils.decode("u2mrp972wh8q"); //Pt(x=18.9671235345304,y=47.64369626529515)
 +
GeohasUtils.decodeBoundary("u2mrp972wh8q"); //Rect(minX=18.967123366892338,maxX=18.967123702168465,minY=47.643696181476116,maxY=47.64369634911418)
 +
</syntaxhighlight>

A lap jelenlegi, 2017. május 16., 13:44-kori változata

A Spatial4j egy általános térinformatikai, open source Java könyvtár (ASL license). A könyvtár 3 területen ad segítséget: közönséges alakzatok euklideszi és geodéziai modellekhez, távolság és egyéb számítások, alakzatok írása/olvasása GeoJSON és WKT(Well Known Text) formátumokból .

Történet

Eredetileg Lucene Spatial Playgroundként (LSP) volt ismert a projekt, később ebből vált ki a Spatial4j, ami már teljes független a Lucene-től. Az LSP többi része a Lucene ill. Solr projektekbe olvadtak bele, vagy átkerültek a Spatial Solr Sandboxba. 2016 februárjától a Spatial4j a LocationTech-hez került (Eclipse).

Függőségek

A könyvtár használatához legalább a Java 1.7-es verziója szükséges. Ha poligonokat és JTS alapú osztályokat (nevük Jts prefixszel kezdődik) szeretnénk használni, akkor ezen felül szükséges a JTS API is (2 dimenziós alakzatok modellezésére és manipulálására szolgál). GeoJSON feldolgozásához pedig a Noggit JSON elemző könyvtárra is szükség lesz.

Alapok

A könyvtár által nyújtott lehetőségeket SpatialContext osztály példányain keresztül érhetjük el. Háromféle módon hozhatunk létre SpatialContext példányokat. Ez egyik, hogy globális, singleton példányt használunk:

 SpatialContext globalContext = SpatialContext.GEO;

A másik esetben pedig a SpatialContextFactory segítségével hozunk létre egy új context példányt:

 SpatialContext nonGeodesicContext = new SpatialContextFactory().newSpatialContext();

A harmadik lehetőséggel létrehozásnál megadhatunk név-érték párokat (ezeket akár egy .property fájlból is felolvashatjuk), melyekkel inicializálódik a SpatialContext példányunk. Ezt a SpatialContextFactory osztály statikus metódusával tehetjük meg:

SpatialContext propertiesContext = SpatialContextFactory.makeSpatialContext(map, classLoader);


Ha poligonokat is akarunk használni, akkor az első két módon lehetőség van a JTS-re épülő megfelelőket használni:

JtsSpatialContext polygonGlobalContext = JtsSpatialContext.GEO;
JtsSpatialContext nonGeodesicPolygonContext = new JtsSpatialContextFactory().newSpatialContext();


A konstruktorok használata nincs megtiltva, azonban mégsem ajánlott, kivéve a SpatialContextFactory esetében. Konstruktorok helyett a különböző factory objektumokat használjuk, melyek a SpatialContext példányokon keresztül érhetőek el.

Alakzatok

A Spatial4J legnagyobb részét az alakzatok teszik ki. Az alakzatok különböző vetületekben is rendelkezésre állnak:

A poligonok a JTS Geometry osztályának csomagolásával vannak megvalósítva. Jelenleg nincs lehetőség a pólusokon levő poligonokkal dolgozni, de tervezik ennek megvalósítását a jövőben. Az alakzatok mindegyike rendelkezik a következő tulajdonságokkal:

  • bounding box kiszámítása
  • terület kiszámítása (néhány alakzatnál ez inkább csak becslés)
  • tartalmaz-e egy adott pontot
  • milyen kapcsolatban áll egy téglalappal: tartalmazza az adott téglalapot (CONTAINS), benne van-e az adott alakzatban (WITHIN), nincs közös pont (DISJOINT). Az érintésre nincs számítás a Spatial4j-ben

A Spatial4J-ben használható alakzatok: Point, Code, Rectangle, LineString, Polygon, ShapeCollection. Alakzatokat a ShapeFactory segítségével tudunk létrehozni:

JtsSpatialContext ctx= JtsSpatialContext.GEO;

Point point = ctx.getShapeFactory().pointXY(10,10);

Circle circle = ctx.getShapeFactory().circle(point, 15); // vagy .circle(10,10,0)

Rectangle r = ctx.getShapeFactory().rectangle(point1, point2); //vagy .rectangle(0,0,10,10)

Shape lineString = ctx.getShapeFactory().lineString()
                .pointXY(0,1)
                .pointXY(2,3)
                .build();

Shape shapeCollection = ctx.getShapeFactory().multiShape(Shape.class)
                .add(p)
                .add(circle)
                .build();

Shape polygon = globalContext.getShapeFactory().polygon()
                .pointXY(0,0)
                .pointXY(2,3)
                .pointXY(10,5)
                .build();

Terület és távolság számítás

Alakzatok írása/olvasása szöveges formátumokból

A Spatial4j segítségével nagyon egyszerűen lehet szöveges formátumokból beolvasni, illetve a különböző alakzatokat ilyen formátumokba kiírni. Az olvasáshoz egy ShapeReader interface-t megvalósító osztály egy példányára lesz szükségünk. Ilyen osztályok, a GeoJSONReader, WKTReader és PolyshapeReader, amik rendre GeoJSON, WKT és Polyshape formátumok olvasására alkalmasa. Az írás hasonlóan működik, ekkor a ShapeWriter interface példányaira van szükség.

A beolvasott adatokból a megfelelő Shape objektumok állnak elő. Íráskor pedig a különböző alakzatainkat tudjuk adott formátumban kiírni.

Az olvasást a ShapeReader által adott read művelettel tudjuk megtenni, aminek vagy egy Obejct vagy egy Reader (java.io.Reader) típusú paramétert vár.


ShapeReader objektumokat kétféleképpen érjük el a SpatialContextből

ShapeReader shapeReader1 = ctx.getFormats().getReader(ShapeIO.GeoJSON);

ShapeReader shapeReader2 = ctx.getFormats().getGeoJsonReader();

Illetve ha írni szeretnénk, akkor hasonlóan jutunk egy ShapeWriter objektumhoz:

ShapeWriter shapeWriter1= ctx.getFormats().getWriter(ShapeIO.GeoJSON);

ShapeWriter shapeWriter2 = ctx.getFormats().getGeoJsonWriter();

Példa egy WKT formátumú fájl beolvasására

A fájl tartalma például legyen a következő:

POINT (19.797752 47.171645)

A beolvasás pedig így működik:

try(FileReader reader = new FileReader(path)){

  SpatialContext ctx = SpatialContext.GEO;
  ShapeReader shapeReader = ctx.getFormats().getWktReader();
  Shape shape = shapeReader.read(reader);
  /*
   Ha kiíratjuk, látszik, hogy a beolvasott alakzatunk egy pont:
   System.out.println(shape);
   Pt(x=19.797752,y=47.171645)
  */
}catch (Exception ex){
  //handle
}

Példa egy alakzat kiírására GeoJSONben

SpatialContext ctx = SpatiaContext.GEO;
ShapeWriter shapeWriter = ctx.getFormats().getGeoJsonWriter();

Point point = ctx.getShapeFactory().pointXY(18.967123,47.643696);

try(FileWriter writer = new FileWriter("path")) {

  shapeWriter.write(writer, shape);

} catch (IOException e) {
  // handle exception        
}

Ezek után a fájlunk tartalma a következő kell legyen:

{"type":"Point","coordinates":[18.967123,47.643696]}

Geohash

GeohashUtils osztály segítségével lehetőségünk van koordináták geohashbe kódolására, valamint geohashből is dekódolhatunk koordinátákat.

A geohash lényege, hogy a Földön található koordinátákat egy rövidebb alakba kódolja. Célja, hogy egy olyan karakter sort kapunk, amivel egyértelműen és kényelmesebben hivatkozhatunk a koordinátákra. Bővebben lásd: Geohash Wikipedia

GeohashUtils.encodeLatLon(47.64369627,18.96712353); //u2mrp972wh8q
GeohashUtils.decode("u2mrp972wh8q"); //Pt(x=18.9671235345304,y=47.64369626529515)
GeohasUtils.decodeBoundary("u2mrp972wh8q"); //Rect(minX=18.967123366892338,maxX=18.967123702168465,minY=47.643696181476116,maxY=47.64369634911418)