#24859 integrated the Geoportal Gis Link

This commit is contained in:
Francesco Mangiacrapa 2023-03-28 15:45:21 +02:00
parent e902fadce2
commit 07730153ca
4 changed files with 293 additions and 275 deletions

View File

@ -1,5 +1,9 @@
# Changelog for org.gcube.application.cms.sdi-plugins # Changelog for org.gcube.application.cms.sdi-plugins
## [v1.1.0-SNAPSHOT]
- Integrated the field 'geov_link' (Geoportal GisViewer link) in the centroid layer [#24859]
## [v1.0.4] - 2023-03-06 ## [v1.0.4] - 2023-03-06
- Fixed the import from joda-time to java.time - Fixed the import from joda-time to java.time
- [#24702] Fixed the default-lc-managers dependency - [#24702] Fixed the default-lc-managers dependency

View File

@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>sdi-plugins</artifactId> <artifactId>sdi-plugins</artifactId>
<version>1.0.4</version> <version>1.1.0-SNAPSHOT</version>
<name>gCube CMS - SDI Plugins</name> <name>gCube CMS - SDI Plugins</name>
@ -85,12 +85,19 @@
<version>1.14</version> <version>1.14</version>
</dependency> </dependency>
<dependency>
<groupId>org.gcube.portlets.user</groupId>
<artifactId>uri-resolver-manager</artifactId>
<version>[1.0.0,2.0.0-SNAPSHOT)</version>
</dependency>
<dependency> <dependency>
<groupId>org.gcube.application.cms</groupId> <groupId>org.gcube.application.cms</groupId>
<artifactId>cms-test-commons</artifactId> <artifactId>cms-test-commons</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -18,6 +18,8 @@ public class DBConstants {
public static final String PROJECT_ID="projectid"; public static final String PROJECT_ID="projectid";
public static final String DISPLAYED="displayed_project"; public static final String DISPLAYED="displayed_project";
public static final String GEOVIEWER_LINK_FIELD="geov_link";
public static final String XCOORD_FIELD="xcoord"; public static final String XCOORD_FIELD="xcoord";

View File

@ -33,6 +33,9 @@ import org.gcube.application.geoportal.common.model.plugins.IndexerPluginDescrip
import org.gcube.application.geoportal.common.model.plugins.PluginDescriptor; import org.gcube.application.geoportal.common.model.plugins.PluginDescriptor;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException; import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
import org.gcube.portlets.user.uriresolvermanager.UriResolverManager;
import org.gcube.portlets.user.uriresolvermanager.resolvers.query.GeoportalResolverQueryStringBuilder;
import org.gcube.portlets.user.uriresolvermanager.resolvers.query.GeoportalResolverQueryStringBuilder.RESOLVE_AS;
import org.geojson.Crs; import org.geojson.Crs;
import org.geojson.GeoJsonObject; import org.geojson.GeoJsonObject;
import org.geojson.LngLatAlt; import org.geojson.LngLatAlt;
@ -42,283 +45,285 @@ import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map;
@Slf4j @Slf4j
public class SDIIndexerPlugin extends SDIAbstractPlugin implements IndexerPluginInterface { public class SDIIndexerPlugin extends SDIAbstractPlugin implements IndexerPluginInterface {
static final PluginDescriptor DESCRIPTOR = new PluginDescriptor(Constants.INDEXER_PLUGIN_ID,
static final PluginDescriptor DESCRIPTOR=new PluginDescriptor(Constants.INDEXER_PLUGIN_ID, IndexerPluginDescriptor.INDEXER);
IndexerPluginDescriptor.INDEXER);
static final ArrayList<BBOXEvaluator> BBOX_EVALUATORS = new ArrayList<>();
static {
DESCRIPTOR.setDescription("SDI Indexer. " + "Manage Centroids layers.");
static final ArrayList<BBOXEvaluator> BBOX_EVALUATORS=new ArrayList<>(); DESCRIPTOR.setVersion(new Semver("1.0.0"));
static { BBOX_EVALUATORS.add(new BBOXPathScanner());
DESCRIPTOR.setDescription("SDI Indexer. " + BBOX_EVALUATORS.add(new BBOXByCoordinatePaths());
"Manage Centroids layers.");
DESCRIPTOR.setVersion(new Semver("1.0.0")); }
BBOX_EVALUATORS.add(new BBOXPathScanner()); @Override
BBOX_EVALUATORS.add(new BBOXByCoordinatePaths()); public PluginDescriptor getDescriptor() {
return DESCRIPTOR;
}
} @Override
public InitializationReport initInContext() throws InitializationException {
@Override InitializationReport report = new InitializationReport();
public PluginDescriptor getDescriptor() { report.setStatus(Report.Status.OK);
return DESCRIPTOR; return report;
} }
/**
@Override * Expected parameters : - indexName (unique) - workspace - flagInternalIndex:
public InitializationReport initInContext() throws InitializationException { * boolean - centroidRecord (OPT)
InitializationReport report = new InitializationReport(); *
report.setStatus(Report.Status.OK); * @param request
return report; * @return
} */
/** @Override
* Expected parameters : public IndexDocumentReport index(IndexDocumentRequest request) throws InvalidPluginRequestException {
* - indexName (unique)
* - workspace log.info("Indexer {} : Serving Index Request {} ", this.getDescriptor().getId(), request);
* - centroidRecord (OPT)
* Project project = request.getDocument();
* @param request UseCaseDescriptor useCaseDescriptor = request.getUseCaseDescriptor();
* @return Document requestArguments = request.getCallParameters();
*/
IndexDocumentReport report = new IndexDocumentReport(request);
@Override
public IndexDocumentReport index(IndexDocumentRequest request) throws InvalidPluginRequestException { try {
// ********* INIT INDEX
log.info("Indexer {} : Serving Index Request {} ",this.getDescriptor().getId(),request); // TODO CACHE
PostgisIndexer indexer = getIndexer(useCaseDescriptor, requestArguments);
Project project =request.getDocument();
UseCaseDescriptor useCaseDescriptor = request.getUseCaseDescriptor(); Document profileConfiguration = getConfigurationFromProfile(useCaseDescriptor).getConfiguration();
Document requestArguments=request.getCallParameters(); log.debug("UseCaseDescriptor Configuration is {} ", profileConfiguration);
IndexDocumentReport report= new IndexDocumentReport(request); // ************* PREPARE RECORD
JSONPathWrapper documentNavigator = new JSONPathWrapper(Serialization.write(project));
try{ Document centroidDoc = new Document();
// ********* INIT INDEX if (requestArguments.containsKey("centroidRecord"))
// TODO CACHE centroidDoc.putAll(requestArguments.get("centroidRecords", Document.class));
PostgisIndexer indexer = getIndexer(useCaseDescriptor,requestArguments); // DEFAULT VALUES
centroidDoc.put(DBConstants.Defaults.PROJECT_ID, project.getId());
Document profileConfiguration =getConfigurationFromProfile(useCaseDescriptor).getConfiguration(); centroidDoc.put(DBConstants.Defaults.DISPLAYED, true);
log.debug("UseCaseDescriptor Configuration is {} ",profileConfiguration);
boolean isInternalIndex = false;
try {
// ************* PREPARE RECORD isInternalIndex = requestArguments.getBoolean("flagInternalIndex");
log.debug("flagInternalIndex read as {} ", isInternalIndex);
} catch (Exception e) {
JSONPathWrapper documentNavigator=new JSONPathWrapper(Serialization.write(project)); // TODO: handle exception
}
Document centroidDoc = new Document(); log.info("flagInternalIndex is {} ", isInternalIndex);
if(requestArguments.containsKey("centroidRecord"))
centroidDoc.putAll(requestArguments.get("centroidRecords",Document.class)); try {
// DEFAULT VALUES log.debug("Trying to generate Geoportal Gis Link...");
centroidDoc.put(DBConstants.Defaults.PROJECT_ID, project.getId()); //Contacting the Geoportal-Resolver via UriResolverManager
centroidDoc.put(DBConstants.Defaults.DISPLAYED,true); UriResolverManager uriResolverManager = new UriResolverManager("GEO");
GeoportalResolverQueryStringBuilder builder = new GeoportalResolverQueryStringBuilder(project.getProfileID(),project.getId());
builder.scope(request.getContext().getId());
// ********************** EVALAUTE POSITION if(isInternalIndex) {
log.debug("indexing UseCaseDescriptor {} : Evaluating Centroid... ", useCaseDescriptor.getId()); builder.resolverAs(RESOLVE_AS.PRIVATE);
SpatialReference reference =null; }else {
List<IdentificationReference> refs=project.getIdentificationReferenceByType(SpatialReference.SPATIAL_REFERENCE_TYPE); builder.resolverAs(RESOLVE_AS.PUBLIC);
if(!refs.isEmpty()){ }
Map<String, String> params = builder.buildQueryParameters();
// Use existing Reference String shortLink = uriResolverManager.getLink(params, true);
log.info("Geoportal GisViewer link is {} ", shortLink);
reference = Serialization.convert(refs.get(0), SpatialReference.class); centroidDoc.put(DBConstants.Defaults.GEOVIEWER_LINK_FIELD, shortLink);
}catch (Exception e) {
log.debug("Using already defined spatial reference " + reference); // TODO: handle exception
}
GeoJsonObject object = Serialization.convert(reference.getGeoJson(), GeoJsonObject.class);
// ********************** EVALAUTE POSITION
GCubeSDILayer.BBOX bbox = GCubeSDILayer.BBOX.fromGeoJSON(object.getBbox()); log.debug("indexing UseCaseDescriptor {} : Evaluating Centroid... ", useCaseDescriptor.getId());
SpatialReference reference = null;
log.info("Found declared BBOX {} ", bbox); List<IdentificationReference> refs = project
Double pointX = (bbox.getMaxX() + bbox.getMinX())/2; .getIdentificationReferenceByType(SpatialReference.SPATIAL_REFERENCE_TYPE);
Double pointY = (bbox.getMaxY() + bbox.getMinY())/2; if (!refs.isEmpty()) {
String wkt = String.format("POINT (%1$f %2$f) ",
pointX, pointY); // Use existing Reference
reference = Serialization.convert(refs.get(0), SpatialReference.class);
centroidDoc.put("geom", wkt);
log.debug("Using already defined spatial reference " + reference);
} else{
// unable to use current Spatial reference, try evaluating it GeoJsonObject object = Serialization.convert(reference.getGeoJson(), GeoJsonObject.class);
log.debug("UseCaseDescriptor {} : Getting evaluation paths from useCaseDescriptor.. ", useCaseDescriptor.getId());
GCubeSDILayer.BBOX bbox = GCubeSDILayer.BBOX.fromGeoJSON(object.getBbox());
// for each configuration option try until found
GCubeSDILayer.BBOX toSet = null; log.info("Found declared BBOX {} ", bbox);
for(BBOXEvaluator evaluator : BBOX_EVALUATORS){ Double pointX = (bbox.getMaxX() + bbox.getMinX()) / 2;
log.trace("UCD {}, Project {}. Evaluating BBOX with {}",useCaseDescriptor.getId(),project.getId(),evaluator); Double pointY = (bbox.getMaxY() + bbox.getMinY()) / 2;
try{ String wkt = String.format("POINT (%1$f %2$f) ", pointX, pointY);
if(evaluator.isConfigured(profileConfiguration)){
toSet=evaluator.evaluate(profileConfiguration,useCaseDescriptor,documentNavigator); centroidDoc.put("geom", wkt);
if(toSet!=null) {
log.info("UCD {}, Project {}. Evaluated BBOX {} with method {}", } else {
useCaseDescriptor.getId(),project.getId(),toSet,evaluator); // unable to use current Spatial reference, try evaluating it
break; log.debug("UseCaseDescriptor {} : Getting evaluation paths from useCaseDescriptor.. ",
} useCaseDescriptor.getId());
}
}catch (Throwable t){ // for each configuration option try until found
log.warn("UCD {}, Project {}. Exception with {}", GCubeSDILayer.BBOX toSet = null;
useCaseDescriptor.getId(),project.getId(),evaluator,t); for (BBOXEvaluator evaluator : BBOX_EVALUATORS) {
} log.trace("UCD {}, Project {}. Evaluating BBOX with {}", useCaseDescriptor.getId(), project.getId(),
} evaluator);
if(toSet== null) try {
throw new IndexingException("No BBOX has been evaluated from project"); if (evaluator.isConfigured(profileConfiguration)) {
toSet = evaluator.evaluate(profileConfiguration, useCaseDescriptor, documentNavigator);
Double pointX=(toSet.getMaxX()+toSet.getMinX())/2; if (toSet != null) {
Double pointY = (toSet.getMaxY()+toSet.getMinY())/2; log.info("UCD {}, Project {}. Evaluated BBOX {} with method {}",
log.info("Evaluated BBOX {} ",toSet); useCaseDescriptor.getId(), project.getId(), toSet, evaluator);
String wkt = String .format("POINT (%1$f %2$f) ", break;
pointX, pointY); }
//TODO support altitude }
Double pointZ= 0d; } catch (Throwable t) {
log.warn("UCD {}, Project {}. Exception with {}", useCaseDescriptor.getId(), project.getId(),
evaluator, t);
centroidDoc.put("geom",wkt); }
}
Point point = new Point(); if (toSet == null)
point.setCoordinates(new LngLatAlt(pointX,pointY,pointZ)); throw new IndexingException("No BBOX has been evaluated from project");
point.setBbox(toSet.asGeoJSONArray());
Double pointX = (toSet.getMaxX() + toSet.getMinX()) / 2;
//TODO Manage CRS Double pointY = (toSet.getMaxY() + toSet.getMinY()) / 2;
point.setCrs(new Crs()); log.info("Evaluated BBOX {} ", toSet);
reference = new SpatialReference(Serialization.asDocument(point)); String wkt = String.format("POINT (%1$f %2$f) ", pointX, pointY);
log.info("UCD {} project {}, Setting Spatial Reference {} ",useCaseDescriptor.getId(),project.getId(),Serialization.write(reference)); // TODO support altitude
report.addIdentificationReference(reference); Double pointZ = 0d;
}
centroidDoc.put("geom", wkt);
Point point = new Point();
//*********** Additional Values from useCaseDescriptor point.setCoordinates(new LngLatAlt(pointX, pointY, pointZ));
point.setBbox(toSet.asGeoJSONArray());
log.info("Setting additional values to centroid from mappings ..");
for(MappingObject m : getMappings(useCaseDescriptor)){ // TODO Manage CRS
List<Object> foundValues = documentNavigator.getByPath(m.getPath()); point.setCrs(new Crs());
Object toSetValue=null; reference = new SpatialReference(Serialization.asDocument(point));
if(!foundValues.isEmpty()) { log.info("UCD {} project {}, Setting Spatial Reference {} ", useCaseDescriptor.getId(), project.getId(),
// NB CSV for multiple values Serialization.write(reference));
StringBuilder b=new StringBuilder(); report.addIdentificationReference(reference);
foundValues.forEach(o-> { }
// Parser returns list of list
if (o instanceof Collection) ((Collection<?>) o).forEach(v ->b.append(v + ",")); // *********** Additional Values from useCaseDescriptor
else b.append(o+",");
}); log.info("Setting additional values to centroid from mappings ..");
b.deleteCharAt(b.length()-1); for (MappingObject m : getMappings(useCaseDescriptor)) {
toSetValue = b.toString(); List<Object> foundValues = documentNavigator.getByPath(m.getPath());
} Object toSetValue = null;
log.trace("Setting {} = {} in centroid doc ",m.getName(),toSetValue); if (!foundValues.isEmpty()) {
centroidDoc.put(m.getName(),toSetValue); // NB CSV for multiple values
} StringBuilder b = new StringBuilder();
foundValues.forEach(o -> {
log.info("Inserting Centroid {} into {} ",Serialization.write(centroidDoc.toJson()),indexer); // Parser returns list of list
indexer.insert(centroidDoc); if (o instanceof Collection)
((Collection<?>) o).forEach(v -> b.append(v + ","));
// Support to HIDE AND DISPLAY as requested by invoker else
if(requestArguments.containsKey("_toHideIds")){ b.append(o + ",");
});
List<String> ids = Serialization.convert(requestArguments.get("_toHideIds"),List.class); b.deleteCharAt(b.length() - 1);
log.info("Requested to hide centroids {} ",ids); toSetValue = b.toString();
indexer.updateIsVisible(false,ids); }
} log.trace("Setting {} = {} in centroid doc ", m.getName(), toSetValue);
centroidDoc.put(m.getName(), toSetValue);
if(requestArguments.containsKey("_toDisplayIds")){ }
List<String> ids = Serialization.convert(requestArguments.get("_toDisplayIds"),List.class);
log.info("Inserting Centroid {} into {} ", Serialization.write(centroidDoc.toJson()), indexer);
log.info("Requested to display centroids {} ",ids); indexer.insert(centroidDoc);
indexer.updateIsVisible(true,ids);
} // Support to HIDE AND DISPLAY as requested by invoker
if (requestArguments.containsKey("_toHideIds")) {
List<String> ids = Serialization.convert(requestArguments.get("_toHideIds"), List.class);
report.setStatus(Report.Status.OK); log.info("Requested to hide centroids {} ", ids);
}catch (SDIInteractionException e){ indexer.updateIsVisible(false, ids);
log.error("Unable to index "+request,e); }
report.setStatus(Report.Status.ERROR);
report.putMessage(e.getMessage()); if (requestArguments.containsKey("_toDisplayIds")) {
}catch (Throwable t){ List<String> ids = Serialization.convert(requestArguments.get("_toDisplayIds"), List.class);
log.error("Unable to index "+request,t);
report.setStatus(Report.Status.ERROR); log.info("Requested to display centroids {} ", ids);
report.putMessage(t.getMessage()); indexer.updateIsVisible(true, ids);
}finally{ }
return report;
} report.setStatus(Report.Status.OK);
} } catch (SDIInteractionException e) {
log.error("Unable to index " + request, e);
private List<MappingObject> getMappings(UseCaseDescriptor useCaseDescriptor) throws InvalidProfileException { report.setStatus(Report.Status.ERROR);
return MappingObject.getMappingsFromUCD(useCaseDescriptor, getDescriptor().getId()); report.putMessage(e.getMessage());
} } catch (Throwable t) {
log.error("Unable to index " + request, t);
@Override report.setStatus(Report.Status.ERROR);
public IndexDocumentReport deindex(IndexDocumentRequest request) throws InvalidPluginRequestException { report.putMessage(t.getMessage());
log.info("Indexer {} : Serving Index Request {} ",this.getDescriptor().getId(),request); } finally {
IndexDocumentReport report= new IndexDocumentReport(request); return report;
try{ }
PostgisIndexer indexer = getIndexer(request.getUseCaseDescriptor(),request.getCallParameters()); }
indexer.removeByFieldValue(PostgisIndexer.StandardFields.PROJECT_ID,request.getDocument().getId());
}catch (SDIInteractionException e){ private List<MappingObject> getMappings(UseCaseDescriptor useCaseDescriptor) throws InvalidProfileException {
log.error("Unable to index "+request,e); return MappingObject.getMappingsFromUCD(useCaseDescriptor, getDescriptor().getId());
report.setStatus(Report.Status.ERROR); }
report.putMessage(e.getMessage());
}catch (Throwable t){ @Override
log.error("Unable to index "+request,t); public IndexDocumentReport deindex(IndexDocumentRequest request) throws InvalidPluginRequestException {
report.setStatus(Report.Status.ERROR); log.info("Indexer {} : Serving Index Request {} ", this.getDescriptor().getId(), request);
report.putMessage(t.getMessage()); IndexDocumentReport report = new IndexDocumentReport(request);
}finally{ try {
return report; PostgisIndexer indexer = getIndexer(request.getUseCaseDescriptor(), request.getCallParameters());
} indexer.removeByFieldValue(PostgisIndexer.StandardFields.PROJECT_ID, request.getDocument().getId());
} } catch (SDIInteractionException e) {
log.error("Unable to index " + request, e);
/** report.setStatus(Report.Status.ERROR);
* Expected parameters : report.putMessage(e.getMessage());
* workspace } catch (Throwable t) {
* indexName log.error("Unable to index " + request, t);
* report.setStatus(Report.Status.ERROR);
* @param request report.putMessage(t.getMessage());
* @return } finally {
* @throws ConfigurationException return report;
*/ }
@Override }
public Index getIndex(BaseRequest request) throws ConfigurationException {
try { /**
return getIndexer(request.getUseCaseDescriptor(), request.getCallParameters()).getIndexConfiguration(); * Expected parameters : workspace indexName
}catch(Throwable t ){ *
throw new ConfigurationException("Unable to get Postgis index for ucd "+request.getUseCaseDescriptor().getId()+" in "+ request.getContext(),t); * @param request
} * @return
} * @throws ConfigurationException
*/
// Inits index @Override
// TODO CACHE public Index getIndex(BaseRequest request) throws ConfigurationException {
private PostgisIndexer getIndexer(UseCaseDescriptor ucd,Document params) throws ConfigurationException, SQLException, InvalidProfileException, SDIInteractionException { try {
PostgisIndexer indexer = new PostgisIndexer(sdiCache.getObject(), ucd, postgisCache.getObject()); return getIndexer(request.getUseCaseDescriptor(), request.getCallParameters()).getIndexConfiguration();
} catch (Throwable t) {
List<MappingObject> mappingObjects = getMappings(ucd); throw new ConfigurationException("Unable to get Postgis index for ucd "
List<PostgisTable.Field> fields = PostgisTable.Field.fromMappings(mappingObjects); + request.getUseCaseDescriptor().getId() + " in " + request.getContext(), t);
}
indexer.initIndex(params.getString("indexName"), }
fields,
params.getString("workspace"), // Inits index
params.getString("indexName")); // TODO CACHE
return indexer; private PostgisIndexer getIndexer(UseCaseDescriptor ucd, Document params)
} throws ConfigurationException, SQLException, InvalidProfileException, SDIInteractionException {
PostgisIndexer indexer = new PostgisIndexer(sdiCache.getObject(), ucd, postgisCache.getObject());
List<MappingObject> mappingObjects = getMappings(ucd);
List<PostgisTable.Field> fields = PostgisTable.Field.fromMappings(mappingObjects);
indexer.initIndex(params.getString("indexName"), fields, params.getString("workspace"),
params.getString("indexName"));
return indexer;
}
} }