„Spatial4J” változatai közötti eltérés
(Új oldal, tartalma: „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 …”) |
|||
(24 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. | + | 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 == | ||
− | 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). | + | 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 == | == 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 [https://sourceforge.net/projects/jts-topo-suite/ 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 [https://github.com/yonik/noggit Noggit JSON] elemző könyvtárra is szükség lesz. | + | A könyvtár használatához legalább a Java 1.7-es verziója szükséges. Ha poligonokat és [https://sourceforge.net/projects/jts-topo-suite/ 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 [https://github.com/yonik/noggit Noggit JSON] elemző könyvtárra is szükség lesz. |
+ | |||
+ | == Alapok == | ||
+ | A könyvtár által nyújtott lehetőségeket <code>SpatialContext</code> 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: | ||
+ | |||
+ | <syntaxhighlight lang="java"> | ||
+ | SpatialContext globalContext = SpatialContext.GEO; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | A másik esetben pedig a <code>SpatialContextFactory</code> segítségével hozunk létre egy új context példányt: | ||
+ | <syntaxhighlight lang="java"> | ||
+ | SpatialContext nonGeodesicContext = new SpatialContextFactory().newSpatialContext(); | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | A harmadik lehetőséggel létrehozásnál megadhatunk név-érték párokat (ezeket akár egy <code>.property</code> fájlból is felolvashatjuk), melyekkel inicializálódik a ''SpatialContext'' példányunk. Ezt a <code>SpatialContextFactory</code> osztály statikus metódusával tehetjük meg: | ||
+ | <syntaxhighlight lang="java"> | ||
+ | SpatialContext propertiesContext = SpatialContextFactory.makeSpatialContext(map, classLoader); | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | 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: | ||
+ | <syntaxhighlight lang="java"> | ||
+ | JtsSpatialContext polygonGlobalContext = JtsSpatialContext.GEO; | ||
+ | JtsSpatialContext nonGeodesicPolygonContext = new JtsSpatialContextFactory().newSpatialContext(); | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | 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 == | ||
+ | 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 <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== | ||
+ | |||
+ | 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 <code>ShapeReader</code> interface-t megvalósító osztály egy példányára lesz szükségünk. Ilyen osztályok, a <code>GeoJSONReader</code>, <code>WKTReader</code> és <code>PolyshapeReader</code>, amik rendre GeoJSON, WKT és Polyshape formátumok olvasására alkalmasa. Az írás hasonlóan működik, ekkor a <code>ShapeWriter</code> interface példányaira van szükség. | ||
+ | |||
+ | 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. | ||
+ | |||
+ | 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>ShapeReader</code> objektumokat kétféleképpen érjük el a ''SpatialContextből'' | ||
+ | |||
+ | <syntaxhighlight lang="java"> | ||
+ | ShapeReader shapeReader1 = ctx.getFormats().getReader(ShapeIO.GeoJSON); | ||
+ | |||
+ | ShapeReader shapeReader2 = ctx.getFormats().getGeoJsonReader(); | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | 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> | ||
+ | |||
+ | ====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., 12: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 .
Tartalomjegyzék
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)