Convert JTS Geometry to ElasticSearch Geometry in Java - java

I'm trying to find a way to convert a JTS Geometry to an ElasticSeach Geometry in order to make a geo query, but I didn't find a convenient way.
Using ElasticSearch 7.11.1 with Java API, to make a geospatial query, I should use a
GeoShapeQueryBuilder
returned by
QueryBuilders.geoShapeQuery(String, org.elasticsearch.geometry.Geometry)
method.
But, in my project, I'm using the JTS geometry (see https://en.wikipedia.org/wiki/JTS_Topology_Suite), where a geometry is an instance of class:
org.locationtech.jts.geom.Geometry
Obviously, I can't cast JTS Geometry to ElasticSearch Geometry, but I should convert the instance is somw way.
Has anyone encountered similar problem?Thank you very much

You can get coordinates from your jts.Geometry object and build whatever elasticsearch.Geometry you need e.g for Polygon you would write something like this:
val coordinates = geometry.coordinates
val mappedCoordinates = coordinates.map { Coordinate(it.x, it.y) }
val toPolygonGeometry = PolygonBuilder(CoordinatesBuilder().coordinates(mappedCoordinates)).toPolygonGeometry()

Related

How to use MLeap DenseTensor in Java

I am using MLeap to run a Pyspark logistic regression model in a java program. Once I run the pipeline I am able to get a DefaultLeapFrame object with one row Stream(Row(1.3,12,3.6,DenseTensor([D#538613b3,List(2)),1.0), ?).
But I am not sure how to actually inspect the DenseTensor object. When I use getTensor(3) on this row I get an object. I am not familiar with Scala but that seems to be how this is meant to be interacted with. In Java how can I get the values within this DenseVector?
Here is roughly what I am doing. I'm guessing using Object is not right for the type. . .
DefaultLeapFrame df = leapFrameSupport.select(frame2, Arrays.asList("feat1", "feat2", "feat3", "probability", "prediction"));
Tensor<Object> tensor = df.dataset().head().getTensor(3);
Thanks
So the MLeap documentation for the Java DSL is not so good but I was able to look over some unit tests (link) that pointed me to the right thing to use. In case anyone else is interested, this is what I did.
DefaultLeapFrame df = leapFrameSupport.select(frame, Arrays.asList("feat1", "feat2", "feat3", "probability", "prediction"));
TensorSupport tensorSupport = new TensorSupport();
List<Double> tensor_vals = tensorSupport.toArray(df.dataset().head().getTensor(3));

How to transform projection EPSG:3857 to EPSG:4326 in java (Geospatial)

Is there a way to transform a EPSG:3857 projection to EPSG:4326 in java? I'm using the esri java sdk. I went through the esri skd docs, but couldn't find a way to transform EPSG:3857 to EPSG:4326. Is there a way of doing it?
I have a webMercator like this: Point property = new Point(1.7040237624799997e7,-3099509.4953500014, SpatialReferences.getWebMercator());
And have a WSG84 like this Point point1 = new Point(153.089361, -26.802295, SpatialReferences.getWgs84());
I need to merge them and as those points have different Spatial References I can't display a map property.
I'm assuming you are using the ArcObjects SDK for Java? Then the following code should work because your Point class is implementing the IGeometry interface according to esri java doc
https://desktop.arcgis.com/en/arcobjects/latest/java/api/arcobjects/com/esri/arcgis/geometry/IGeometry.html
Point property = new Point(1.7040237624799997e7,-3099509.4953500014,
spatialReferences.getWebMercator());
Point reprojected = property.project(SpatialReferences.getWgs84());
Because your Point constructor looks like you're using one of the newer Esri SDKs like ArcGIS Pro SDK or Runtime SDK I'm adding a solution for them too:
Point originalPoint = new Point(1.7040237624799997e7,-3099509.4953500014,
spatialReferences.getWebMercator());
Point projectedPoint = (Point) GeometryEngine.project(originalPoint,
SpatialReference.create(4326));
according to
https://developers.arcgis.com/java/latest/sample-code/project.htm

Shortest path with ArangoDB & Java

I read in the documentation that ArangoDB is migrating functions from AQL to native.
I was trying the shortest path example:
ArangoDB arangoDB = new ArangoDB.Builder().build();
ArangoGraph g = arangoDB.db().graph("routeplanner");
Can I continue implementing without using AQL like in the shell example? How can I do?
PS: Are edges bidirectional? Can I go from Cologne to Hamburg?
The graph functions are only accessible over the arango shell or foxx services. They aren't provided by the HTTP API which is used by the Java driver.
When using the Java driver (or any other driver) you have to use AQL for shortest path or other graph functionality from the docs.
Edges in ArangoDB are always directional (an edge document always has the fields "_from", "_to") but you can define the direction edges are followed in the query within it (see docs).
FOR v, e
IN ANY SHORTEST_PATH
'germanCity/Cologne' TO 'germanCity/Hamburg'
GRAPH 'routeplanner'
OPTIONS {weightAttribute:'distance'}
RETURN [v._key, e._key]

Gremlin get all incoming and outgoing vertex, including their edges and directions

I spent a week at Gremlin shell trying to compose one query to
get all incoming and outgoing vertexes, including their edges and directions. All i tried everything.
g.V("name","testname").bothE.as('both').select().back('both').bothV.as('bothV').select(){it.map()}
output i need is (just example structure ):
[v{'name':"testname"}]___[ine{edge_name:"nameofincomingedge"}]____[v{name:'nameofconnectedvertex']
[v{'name':"testname"}]___[oute{edge_name:"nameofoutgoingedge"}]____[v{name:'nameofconnectedvertex']
So i just whant to get 1) all Vertices with exact name , edge of each this vertex (including type inE or outE), and connected Vertex. And ideally after that i want to get their map() so i'l get complete object properties. i dont care about the output style, i just need all of information present, so i can manipulate with it after. I need this to train my Gremlin, but Neo4j examples are welcome. Thanks!
There's a variety of ways to approach this. Here's a few ideas that will hopefully inspire you to an answer:
gremlin> g = TinkerGraphFactory.createTinkerGraph()
==>tinkergraph[vertices:6 edges:6]
gremlin> g.V('name','marko').transform{[v:it,inE:it.inE().as('e').outV().as('v').select().toList(),outE:it.outE().as('e').inV().as('v').select().toList()]}
==>{v=v[1], inE=[], outE=[[e:e[9][1-created->3], v:v[3]], [e:e[7][1-knows->2], v:v[2]], [e:e[8][1-knows->4], v:v[4]]]}
The transform converts the incoming vertex to a Map and does internal traversal over in/out edges. You could also use path as follows to get a similar output:
gremlin> g.V('name','marko').transform{[v:it,inE:it.inE().outV().path().toList().toList(),outE:it.outE().inV().path().toList()]}
==>{v=v[1], inE=[], outE=[[v[1], e[9][1-created->3], v[3]], [v[1], e[7][1-knows->2], v[2]], [v[1], e[8][1-knows->4], v[4]]]}
I provided these answers using TinkerPop 2.x as that looked like what you were using as judged from the syntax. TinkerPop 3.x is now available and if you are just getting started, you should take a look at the latest that has to offer:
http://tinkerpop.incubator.apache.org/
Under 3.0 syntax you might do something like this:
gremlin> g.V().has('name','marko').as('a').bothE().bothV().where(neq('a')).path()
==>[v[1], e[9][1-created->3], v[3]]
==>[v[1], e[7][1-knows->2], v[2]]
==>[v[1], e[8][1-knows->4], v[4]]
I know that you wanted to know what the direction of the edge in the output but that's easy enough to detect on analysis of the path.
UPDATE: Here's the above query written with Daniel's suggestion of otherV usage:
gremlin> g.V().has('name','marko').bothE().otherV().path()
==>[v[1], e[9][1-created->3], v[3]]
==>[v[1], e[7][1-knows->2], v[2]]
==>[v[1], e[8][1-knows->4], v[4]]
To see the data from this you can use by() to pick apart each Path object - The extension to the above query applies valueMap to each piece of each Path:
gremlin> g.V().has('name','marko').bothE().otherV().path().by(__.valueMap(true))
==>[{label=person, name=[marko], id=1, age=[29]}, {label=created, weight=0.4, id=9}, {label=software, name=[lop], id=3, lang=[java]}]
==>[{label=person, name=[marko], id=1, age=[29]}, {label=knows, weight=0.5, id=7}, {label=person, name=[vadas], id=2, age=[27]}]
==>[{label=person, name=[marko], id=1, age=[29]}, {label=knows, weight=1.0, id=8}, {label=person, name=[josh], id=4, age=[32]}]

Extracting Geometry from IFC File

I have to extract the geometry of a ifc file in JAVA. My problem is, that i don't know how to do it.
I tried to use openifctools but the documentation is really bad. For now i have the ifc file loaded, but i cannot get the geometry out of the model.
Does anyone have experience with ifc model loading?
Thanks in advance.
EDIT: This is what I've done so far
try {
IfcModel ifcModel = new IfcModel();
ifcModel.readStepFile(new File("my-project.ifc"));
Collection<IfcClass> ifcObjects = ifcModel.getIfcObjects();
System.out.println(ifcObjects.iterator().next());
} catch (Exception e) {
e.printStackTrace();
}
This correctly loads the ifc file. But I don't know what to do with this information.
I also tried to use IfcOpenShell but the provided jar container hadn't worked either. At the moment I try to build IfcOpenShell by myself.
I'm kinda desperate because everything is very undocumented and I really need to load and parse the ifc geometry.
Depending on what you want to do with the geometry, how deep you want to delve into the IFC standard and what performance you need for your solution you have two different options:
Extract the implicit geometry on your own
Use an external geometry engine
If you go for the first option, you'd have to study the IFC schema intensively. You would only be interested in IFCProducts, because only those can have geometry. Using OpenIfcTools you could do something like:
Collection<IfcProduct> products = model.getCollection(IfcProduct.class);
for(IfcProduct product: products){
List<IfcRepresentation> representations = product.getRepresentation().getRepresentations();
assert ! representations.isEmpty();
assert representations.get(0) instanceof IfcShapeRepresentation:
Collection<IfcRepresentationItem> repr = representations.get(0).getItems();
assert !repr.isEmpty();
IfcRepresentationItem representationItem = repr.iterator().next();
assert representationItem instanceof IfcFacetedBrep;
for(IfcFace face: ((IfcFacetedBrep)representationItem).getOuter().getCfsFaces()){
for(IfcFaceBound faceBound: face.getBounds()){
IfcLoop loop = faceBound.getBound();
assert loop instanceof IfcPolyLoop;
for(IfcCartesianPoint point: ((IfcPolyLoop) loop).getPolygon()){
point.getCoordinates();
}
}
}
}
However, there are a lot of different GeometryRepresentations, which you'd have to cover, probably doing triangulation and stuff on your own. I've shown one special case and made a lot of assertions. And you'd have to fiddle with coordinate transformations, because these may be nested recursively.
If you go for the second option the geometry engines I know are all written in C/C++ (Ifcopenshell, RDF IfcEngine), so you'd have to cope with native library integration. The jar package provided with IFCOpenshell is intended to be used as a Bimserver plugin. Those you can't use it without the respective dependencies. However you can grab the native binaries from this package. In order to use the engine you can draw some inspiration from the Bimserver plugin source. The key native methods you're gonna use are
boolean setIfcData(byte[] ifc) to parse the ifc data
IfcGeomObject getGeometry() to access the extracted geometry successively.

Categories