This commit is contained in:
Fabio Sinibaldi 2022-03-07 17:59:06 +01:00
parent 16bc565aed
commit 6afc72b304
22 changed files with 355 additions and 39 deletions

View File

@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import org.bson.Document;
import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException;
import org.gcube.application.cms.plugins.faults.PluginExecutionException;
import org.gcube.application.cms.plugins.requests.IndexDocumentRequest;
@ -16,7 +17,7 @@ import org.gcube.application.geoportal.common.model.document.temporal.TemporalRe
public class IndexDocumentReport extends DocumentHandlingReport<IndexDocumentRequest> {
public TemporalReference toSetTemporalReference;
public SpatialReference toSetSpatialReference;
public Document toSetSpatialReference;
public IndexDocumentReport(@NonNull IndexDocumentRequest theRequest) throws InvalidPluginRequestException {

View File

@ -1,9 +1,14 @@
package org.gcube.application.cms.plugins.reports;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.*;
import org.bson.Document;
import org.gcube.application.cms.plugins.faults.InvalidPluginRequestException;
import org.gcube.application.cms.plugins.faults.PluginExecutionException;
import org.gcube.application.cms.plugins.requests.EventExecutionRequest;
import org.gcube.application.cms.plugins.requests.StepExecutionRequest;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.document.temporal.TemporalReference;
import java.util.ArrayList;
import java.util.List;
@ -25,6 +30,10 @@ public class StepExecutionReport extends DocumentHandlingReport<StepExecutionReq
List<StepExecutionRequest> cascadeSteps;
public TemporalReference toSetTemporalReference;
public Document toSetSpatialReference;
public StepExecutionReport addToTriggerEvent(EventExecutionRequest req){
if(toTriggerEvents==null) toTriggerEvents = new ArrayList<>();
toTriggerEvents.add(req);
@ -37,4 +46,12 @@ public class StepExecutionReport extends DocumentHandlingReport<StepExecutionReq
cascadeSteps.add(req);
return this;
}
@Override
public Project prepareResult() throws JsonProcessingException, PluginExecutionException {
Project toReturn= super.prepareResult();
if(toSetSpatialReference != null) toReturn.setSpatialReference(toSetSpatialReference);
if(toSetTemporalReference != null) toReturn.setTemporalReference(toSetTemporalReference);
return toReturn;
}
}

View File

@ -23,7 +23,7 @@ public class TestDocuments {
documentMap.put(f.getName(), p);
}
} catch (IOException e) {
throw new RuntimeException("Unable to read "+f.getAbsolutePath(),e);
System.err.println("WARN : Unable to read file "+f.getAbsolutePath());
}
}
}

View File

@ -169,10 +169,12 @@ public class ConcessioniLifeCycleManager implements LifecycleManager {
IndexDocumentReport indexReport = indexerPlugin.index(indexRequest);
switch(indexReport.getStatus()){
case OK : {
info.setPhase("PUBLISHED");
report.setToSetSpatialReference(indexReport.getToSetSpatialReference());
break;
}
case ERROR : {

View File

@ -1,5 +1,6 @@
package org.gcube.application.geoportal.clients;
import org.bson.Document;
import org.gcube.application.geoportal.client.utils.Queries;
import org.gcube.application.geoportal.common.model.rest.QueryRequest;
import org.gcube.application.geoportal.common.rest.UseCaseDescriptorsI;
@ -29,6 +30,10 @@ public class UCDTests {
// All
AtomicLong counter = new AtomicLong(0l);
client.query(request).forEachRemaining(u ->counter.incrementAndGet());
// Filter by presence of handler Id
request.setFilter(Document.parse("{\"_handlers._id\" : {\"$eq\" : \"org.gcube....geoportal-data-entry-portlet\"}}"));
System.out.println("Count : "+counter.get());
}

View File

@ -53,7 +53,7 @@ public class Project {
// Expected GEOJSON
@JsonProperty(SPATIAL_REFERENCE)
private SpatialReference spatialReference;
private Document spatialReference;
@JsonProperty(TEMPORAL_REFERENCE)
private TemporalReference temporalReference;

View File

@ -1,5 +1,6 @@
package org.gcube.application.geoportal.common.model.document.filesets;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.bson.Document;
@ -10,8 +11,58 @@ public class GCubeSDILayer extends Materialization{
@Data
@NoArgsConstructor
/**
* A GeoJSON object MAY have a member named "bbox" to include
* information on the coordinate range for its Geometries, Features, or
* FeatureCollections. The value of the bbox member MUST be an array of
* length 2*n where n is the number of dimensions represented in the
* contained geometries, with all axes of the most southwesterly point
* followed by all axes of the more northeasterly point. The axes order
* of a bbox follows the axes order of geometries.
*
* source https://datatracker.ietf.org/doc/html/rfc7946#section-5
*/
public static class BBOX extends Document {
public final String asGeoJSONBBox(){
StringBuilder builder = new StringBuilder("[");
builder.append(getMaxX()+","); // W
builder.append(getMinY()+","); // S
if(is3d()) builder.append(getMinZ()+","); // Z
builder.append(getMinX()+","); // E
builder.append(getMaxY()+","); // N
if(is3d()) builder.append(getMaxZ()+","); // Z
builder.deleteCharAt(builder.length());
builder.append("]");
return builder.toString();
}
public double[] asGeoJSONArray(){
if(is3d()){
return new double[]{getMaxX(),getMinY(),getMinZ(),getMinX(),getMaxY(),getMaxZ()};
}else return new double[]{getMaxX(),getMinY(),getMinX(),getMaxY()};
}
public static final BBOX fromGeoJSON(double[] coords){
BBOX toReturn = new BBOX();
toReturn.setMaxX(coords[0]);
toReturn.setMinY(coords[1]);
if(coords.length == 6){
// 3D
toReturn.setMinZ(coords[2]);
toReturn.setMinX(coords[3]);
toReturn.setMaxY(coords[4]);
toReturn.setMaxZ(coords[5]);
}else {
toReturn.setMinX(coords[2]);
toReturn.setMaxY(coords[3]);
}
return toReturn;
}
public static final BBOX WORLD=new BBOX(180d,90d,-180d,-90d);
public static final BBOX WORLD_3D=new BBOX(180d,90d,-180d,-90d);
@ -36,19 +87,35 @@ public class GCubeSDILayer extends Materialization{
setMinY(minY);
}
@JsonIgnore
public void setMaxX(Double d){this.put(MAX_X,d);}
@JsonIgnore
public void setMaxY(Double d){this.put(MAX_Y,d);}
@JsonIgnore
public void setMaxZ(Double d){this.put(MAX_Z,d);}
@JsonIgnore
public void setMinX(Double d){this.put(MIN_X,d);}
@JsonIgnore
public void setMinY(Double d){this.put(MIN_Y,d);}
@JsonIgnore
public void setMinZ(Double d){this.put(MIN_Z,d);}
@JsonIgnore
public Double getMinY(){return (Double) this.getOrDefault(MIN_Y,-90d);}
@JsonIgnore
public Double getMaxY(){return (Double) this.getOrDefault(MAX_Y,90d);}
@JsonIgnore
public Double getMinX(){return (Double) this.getOrDefault(MIN_X,-180d);}
@JsonIgnore
public Double getMaxX(){return (Double) this.getOrDefault(MAX_X,180d);}
@JsonIgnore
public Double getMinZ(){return (Double) this.getOrDefault(MIN_Z,null);}
@JsonIgnore
public Double getMaxZ(){return (Double) this.getOrDefault(MAX_Z,null);}
@JsonIgnore
public Boolean is3d(){
return getMinZ()!=null && getMaxZ() !=null;
}
}
@ -61,8 +128,11 @@ public class GCubeSDILayer extends Materialization{
super(GCUBE_SDY_LAYER_TYPE);
}
@JsonIgnore
public List getOGCLinks(){return this.get(OGC_LINKS, List.class);}
@JsonIgnore
public Object getBBox(){return this.get(B_BOX);}
@JsonIgnore
public List getPlatformInfo(){return this.get(PLATFORM_INFO,List.class);}
}

View File

@ -1,5 +1,6 @@
package org.gcube.application.geoportal.common.model.document.filesets;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.*;
import org.bson.Document;
@ -8,9 +9,11 @@ public class Materialization extends Document {
public static final String TYPE ="_type";
@JsonIgnore
public String getType(){return super.getString(TYPE);}
public Materialization(){super();}
@JsonIgnore
public Materialization (String type){
this.put(TYPE,type);
}

View File

@ -1,5 +1,6 @@
package org.gcube.application.geoportal.common.model.document.filesets;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.*;
import org.bson.Document;
@ -18,15 +19,16 @@ public class RegisteredFileSet extends Document {
public static final String PAYLOADS="_payloads";
public static final String MATERIALIZATIONS="_materializations";
@JsonIgnore
public Object getCreationInfo(){ return this.get(CREATION_INFO); }
@JsonIgnore
public Object getAccess(){ return this.get(ACCESS); }
@JsonIgnore
public String getFolderId(){ return super.getString(FOLDER_ID); }
@JsonIgnore
public List getPayloads(){return super.get(PAYLOADS,List.class);}
@JsonIgnore
public List getMaterializations(){return super.get(MATERIALIZATIONS,List.class);}
@JsonIgnore
public String getUUID(){return super.getString(UUID);}
}

View File

@ -1,5 +1,6 @@
package org.gcube.application.geoportal.common.model.document.lifecycle;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;
@ -38,26 +39,27 @@ public class LifecycleInformation {
@JsonProperty(TRIGGERED_EVENTS)
private List<TriggeredEvents> triggeredEvents;
@JsonIgnore
public LifecycleInformation addErrorMessage(String msg){
if(errorMessages==null)
errorMessages=new ArrayList<>();
errorMessages.add(msg);
return this;
}
@JsonIgnore
public LifecycleInformation addWarningMessage(String msg){
if(warningMessages==null)
warningMessages=new ArrayList<>();
warningMessages.add(msg);
return this;
}
@JsonIgnore
public LifecycleInformation addEventReport(TriggeredEvents info){
if(triggeredEvents==null) triggeredEvents=new ArrayList<>();
triggeredEvents.add(info);
return this;
}
@JsonIgnore
public LifecycleInformation cleanState(){
setLastOperationStatus(null);
setLastInvokedStep(null);

View File

@ -1,5 +1,6 @@
package org.gcube.application.geoportal.common.model.useCaseDescriptor;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.*;
import org.bson.Document;
import org.bson.types.MaxKey;
@ -22,35 +23,43 @@ public class Field extends Document {
public static final String MIN_CARDINALITY="_min";
public static final String LABEL="_label";
@JsonIgnore
public String getLabel(){
return this.getString(LABEL);
}
@JsonIgnore
public String getType(){
return this.getString(TYPE);
};
@JsonIgnore
public Boolean isLeaf(){
List children = getChildren();
return children == null || children.isEmpty() || children.get(0)==null;
}
@JsonIgnore
public List getChildren(){
return this.get(CHILDREN,List.class);
}
@JsonIgnore
public Boolean isCollection() {
Integer maxCard=this.getMaxCardinality();
return (maxCard>1||maxCard<0); // Negative values for unbounded
}
@JsonIgnore
public Integer getMaxCardinality(){
return (Integer) this.getOrDefault(MAX_CARDINALITY,1);
}
@JsonIgnore
public Integer getMinCardinality(){
return (Integer) this.getOrDefault(MIN_CARDINALITY,0);
}
@JsonIgnore
public Boolean isMandatory(){
return getMinCardinality()==0;
}

View File

@ -7,6 +7,7 @@ import java.util.Map;
import javax.xml.bind.annotation.XmlRootElement;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.vdurmont.semver4j.Semver;
import lombok.Data;
@ -62,6 +63,8 @@ public class UseCaseDescriptor {
* Returns map Type -> Handler Declaration
* @return
*/
@JsonIgnore
public Map<String,List<HandlerDeclaration>> getHandlersMapByType(){
HashMap<String,List<HandlerDeclaration>> toReturn=new HashMap<>();
handlers.forEach(h->{
@ -78,6 +81,7 @@ public class UseCaseDescriptor {
* Returns map Type -> Handler Declaration
* @return
*/
@JsonIgnore
public Map<String,List<HandlerDeclaration>> getHandlersMapByID(){
HashMap<String,List<HandlerDeclaration>> toReturn=new HashMap<>();
handlers.forEach(h->{

View File

@ -11,8 +11,8 @@ public class GCubeTest {
}
// testContext = "/pred4s/preprod/preVRE";
testContext = "/gcube/devsec/devVRE";
testContext = "/pred4s/preprod/preVRE";
// testContext = "/gcube/devsec/devVRE";
System.out.println("TEST CONTEXT = "+testContext);

View File

@ -77,10 +77,10 @@ public class ConcessioniMongoManager extends MongoManager{
return Serialization.read(d.toJson(), Concessione.class);
}
@Override
protected String mongoIDFieldName() {
return ID;
}
/****************************** PUBLIC METHODS ***********************/

View File

@ -44,6 +44,8 @@ public abstract class MongoManager {
// TODO check if existing DB
protected abstract MongoDatabase getDatabase();
protected abstract String mongoIDFieldName();
//*********** PROJECTS
// NB BsonId
protected ObjectId insert(Document proj, String collectionName) {
@ -51,10 +53,10 @@ public abstract class MongoManager {
MongoCollection<Document> collection = database.getCollection(collectionName);
// Check if _id is present
ObjectId id=proj.getObjectId(ID);
ObjectId id=proj.getObjectId(mongoIDFieldName());
if(id==null) {
proj.append(ID, new ObjectId());
id=proj.getObjectId(ID);
proj.append(mongoIDFieldName(), new ObjectId());
id=proj.getObjectId(mongoIDFieldName());
}
@ -65,7 +67,7 @@ public abstract class MongoManager {
public void delete(ObjectId id, String collectionName) {
MongoDatabase database=getDatabase();
MongoCollection<Document> collection = database.getCollection(collectionName);
collection.deleteOne(eq(ID,id));
collection.deleteOne(eq(mongoIDFieldName(),id));
}
@ -73,7 +75,7 @@ public abstract class MongoManager {
public Document getById(ObjectId id,String collectionName) {
MongoDatabase database=getDatabase();
MongoCollection<Document> coll=database.getCollection(collectionName);
return coll.find(new Document(ID,id)).first();
return coll.find(new Document(mongoIDFieldName(),id)).first();
}
@ -129,7 +131,7 @@ public abstract class MongoManager {
MongoDatabase database=getDatabase();
MongoCollection<Document> coll=database.getCollection(collectionName);
return coll.findOneAndReplace(
eq(ID,id), toUpdate,new FindOneAndReplaceOptions().returnDocument(ReturnDocument.AFTER));
eq(mongoIDFieldName(),id), toUpdate,new FindOneAndReplaceOptions().returnDocument(ReturnDocument.AFTER));
}
@ -137,7 +139,7 @@ public abstract class MongoManager {
MongoDatabase database=getDatabase();
MongoCollection<Document> coll=database.getCollection(collectionName);
return coll.findOneAndUpdate(
eq(ID,id),
eq(mongoIDFieldName(),id),
updateSet,
new FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER));
}

View File

@ -67,8 +67,10 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI<
UseCaseDescriptor useCaseDescriptor;
MongoDatabase db=null;
@Override
protected String mongoIDFieldName() {
return ID;
}
public ProfiledMongoManager(String profileId) throws ConfigurationException, RegistrationException {
// Check UseCaseDescriptor ID

View File

@ -18,6 +18,7 @@ import org.gcube.application.geoportal.common.model.rest.QueryRequest;
import org.gcube.application.geoportal.common.utils.ContextUtils;
import org.gcube.application.geoportal.service.engine.providers.ProfileMapCache;
import org.gcube.application.geoportal.service.model.internal.faults.RegistrationException;
import org.gcube.application.geoportal.service.rest.UseCaseDescriptors;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
@ -44,6 +45,11 @@ public class UCDMongoManager extends MongoManager implements UCDManagerI{
return db;
}
@Override
protected String mongoIDFieldName() {
return UseCaseDescriptor.MONGO_ID;
}
private String getCollectionName(){
return "profiles_"+ContextUtils.getCurrentScope();
}

View File

@ -27,12 +27,19 @@ public class MongoTests {
public MongoTester() throws ConfigurationException {
}
public MongoCollection<Document> getCollection(){return getDatabase().getCollection("legacyConcessioni");}
@Override
protected MongoDatabase getDatabase() {
return client.getTheClient().getDatabase("gna_dev");
}
@Override
protected String mongoIDFieldName() {
return ID;
}
}

View File

@ -49,10 +49,21 @@ public class ProfiledConcessioniTests extends AbstractProfiledDocumentsTests{
System.out.println("Registered posizionamento, result is "+ Serialization.write(doc));
// invoke step SUBMIT-FOR-REVIEW
StepExecutionRequest req=new StepExecutionRequest();
req.setStepID("SUBMIT-FOR-REVIEW");
doc=step(doc.getId(),req);
StepExecutionRequest submitReq=new StepExecutionRequest();
submitReq.setStepID("SUBMIT-FOR-REVIEW");
doc=step(doc.getId(),submitReq);
System.out.println(doc);
assertTrue(doc.getLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK));
// invoke step Publish
StepExecutionRequest approveDraftReq=new StepExecutionRequest();
approveDraftReq.setStepID("APPROVE DRAFT");
doc=step(doc.getId(),approveDraftReq);
System.out.println(doc);
assertTrue(doc.getLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK));
assertTrue(doc.getSpatialReference()!=null);
System.out.println("Project "+doc.getId()+" published with spatial reference "+doc.getSpatialReference().toJson());
}
}

View File

@ -63,6 +63,14 @@
</dependency>
<!-- GEO JSON -->
<dependency>
<groupId>de.grundid.opendatalab</groupId>
<artifactId>geojson-jackson</artifactId>
<version>1.14</version>
</dependency>
</dependencies>

View File

@ -23,6 +23,10 @@ import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.document.filesets.GCubeSDILayer;
import org.gcube.application.geoportal.common.model.document.spatial.SpatialReference;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
import org.geojson.Crs;
import org.geojson.GeoJsonObject;
import org.geojson.LngLatAlt;
import org.geojson.Point;
import java.util.ArrayList;
import java.util.List;
@ -143,7 +147,21 @@ public class SDIIndexerPlugin extends SDIAbstractPlugin implements IndexerPlugin
log.debug("indexing UseCaseDescriptor {} : Evaluating Centroid... ", useCaseDescriptor.getId());
if(project.getSpatialReference()!=null){
log.debug("Using user defined spatial reference "+ project.getSpatialReference());
//TODO USE GEOJSON Position
GeoJsonObject object = Serialization.convert(project.getSpatialReference(), GeoJsonObject.class);
GCubeSDILayer.BBOX bbox= GCubeSDILayer.BBOX.fromGeoJSON( object.getBbox());
log.info("Found declared BBOX {} ",bbox);
Double pointX=(bbox.getMaxX()-bbox.getMinX());
Double pointY = bbox.getMaxY()-bbox.getMinY();
String wkt = String .format("POINT (%1$f %2$f) ",
pointX, pointY);
centroidDoc.put("geom",wkt);
throw new Exception("Not yet implemented");
}else {
log.debug("UseCaseDescriptor {} : Getting evaluation paths from useCaseDescriptor.. ", useCaseDescriptor.getId());
@ -173,16 +191,23 @@ public class SDIIndexerPlugin extends SDIAbstractPlugin implements IndexerPlugin
throw new IndexingException("No BBOX has been found on paths : "+bboxEvaluationPaths);
Double pointX=(toSet.getMaxX()-toSet.getMinX());
Double pointY = toSet.getMaxY()-toSet.getMinY();
log.info("Evaluated BBOX {} ",toSet);
String wkt = String .format("POINT (%1$f %2$f) ",
(toSet.getMaxX()-toSet.getMinX()),
toSet.getMaxY()-toSet.getMinY());
pointX, pointY);
// TODO SET Spatial reference
centroidDoc.put("geom",wkt);
Point toSetSpatialReference = new Point();
LngLatAlt pointCoordinates = new LngLatAlt();
pointCoordinates.setLongitude(pointX);
pointCoordinates.setLatitude(pointY);
toSetSpatialReference.setCoordinates(pointCoordinates);
toSetSpatialReference.setBbox(toSet.asGeoJSONArray());
report.setToSetSpatialReference(Serialization.asDocument(toSetSpatialReference));
}
@ -203,8 +228,6 @@ public class SDIIndexerPlugin extends SDIAbstractPlugin implements IndexerPlugin
log.info("Inserting Centroid {} into {} ",centroidDoc.toJson(),indexer);
indexer.insert(centroidDoc);
// TODO GEOJSON
report.setToSetSpatialReference(new SpatialReference());
report.setStatus(Report.Status.OK);
}catch (SDIInteractionException e){
log.error("Unable to index "+request,e);

View File

@ -0,0 +1,142 @@
{
"_id": "622625b4af5159176f7c550c",
"_version": "1.0.1",
"_info":
{
"_creationInfo":
{
"_user":
{
"_username": "FAKE"
},
"_context":
{
"_id": "/pred4s/preprod/preVRE",
"_name": "/preVRE"
},
"_instant": "2022-03-07T16:33:06.959"
},
"_lastEditInfo":
{
"_user":
{
"_username": "FAKE"
},
"_context":
{
"_id": "/pred4s/preprod/preVRE",
"_name": "/preVRE"
},
"_instant": "2022-03-07T16:33:13.858"
},
"_access":
{
"_policy": "OPEN",
"_license": ""
}
},
"_profileID": "profiledConcessioni",
"_profileVersion": "1.0.0",
"_lifecycleInformation":
{
"_phase": "PUBLISHED",
"_lastInvokedStep": "APPROVE DRAFT",
"_lastOperationStatus": "OK",
"_errorMessages":
[],
"_warningMessages":
[],
"_triggeredEvents":
[]
},
"_relationships": null,
"_spatialReference":
{
"type": "Point",
"bbox":
[
8.621178639172953,
40.62975046683799,
40.630257904721645,
8.62091913167495
],
"coordinates":
[
-32.00907926554869,
-32.00883133516304
]
},
"_temporalReference": null,
"_theDocument":
{
"posizionamentoScavo":
{
"titolo": "mio titolo",
"fileset":
{
"_uuid": "95421181-001c-4e97-bc39-b2e04a30c7b7",
"_creationInfo":
{
"_user":
{
"_username": "FAKE"
},
"_context":
{
"_id": "/pred4s/preprod/preVRE",
"_name": "/preVRE"
},
"_instant": "2022-03-07T16:33:11.167"
},
"_access":
{
"_policy": "OPEN",
"_license": ""
},
"_folderID": "2520ccdd-e0aa-4406-ba62-d900078372ce",
"_payloads":
[
{
"_mimetype": "application/x-shapefile",
"_storageID": "785efad8-3dfc-4de6-bc51-635139722fe7",
"_link": "https://data-pre.d4science.org/shub/E_c3hDNG51b09lcHA3aDU1cVN5RWxzRy9OK2hXblJQTkxKMUxSdnQ4MGRNcnRFTDNQNGQyOG5BUjZjcHREL2k3ag==",
"_name": "pos.shp"
}
],
"_materializations":
[
{
"_type": "gcube-sdi-layer",
"_ogcLinks":
[
{
"wms": "https://geoserver1-t.pre.d4science.org/geoserver/profiledconcessioni_pred4s_preprod_prevre_622625b4af5159176f7c550c/wms?service=WMS&version=1.1.0&request=GetMap&layers=profiledconcessioni_pred4s_preprod_prevre_622625b4af5159176f7c550c:pos&styles=&bbox=8.620919,40.629750,8.621179,40.630258&srs=EPSG:4326&format=application/openlayers&width=400&height=400"
}
],
"_bbox":
{
"_maxX": 8.621178639172953,
"_minX": 40.630257904721645,
"_maxY": 8.62091913167495,
"_minY": 40.62975046683799
},
"_platformInfo":
[
{
"_type": "Geoserver",
"workspace": "profiledconcessioni_pred4s_preprod_prevre_622625b4af5159176f7c550c",
"layerName": "pos",
"persistencePath": "profiledConcessioni/622625b4af5159176f7c550c/95421181-001c-4e97-bc39-b2e04a30c7b7/pos",
"files":
[
"pos.shp"
],
"storeName": "pos_store"
}
]
}
]
}
}
}
}