Commit 2ea7cbad authored by Jörg Richter's avatar Jörg Richter

Remove geomaps module from standard distro (#260)

parent 4dd865d5
Pipeline #8782 passed with stages
in 5 minutes and 18 seconds
......@@ -44,7 +44,6 @@
<bundle>mvn:systems.dmx/deepamehta-events/${project.version}</bundle>
<bundle>mvn:systems.dmx/deepamehta-datetime/${project.version}</bundle>
<bundle>mvn:systems.dmx/deepamehta-webbrowser/${project.version}</bundle>
<bundle>mvn:systems.dmx/deepamehta-geomaps/${project.version}</bundle>
</feature>
</features>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<name>DMX Geomaps</name>
<groupId>systems.dmx</groupId>
<artifactId>dmx-geomaps</artifactId>
<version>5.0-beta-7-SNAPSHOT</version>
<packaging>bundle</packaging>
<parent>
<groupId>systems.dmx</groupId>
<artifactId>dmx-plugin</artifactId>
<version>5.0-beta-7-SNAPSHOT</version>
<relativePath>../dmx-plugin/pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>systems.dmx</groupId>
<artifactId>dmx-topicmaps</artifactId>
<version>5.0-beta-7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>systems.dmx</groupId>
<artifactId>dmx-facets</artifactId>
<version>5.0-beta-7-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
<Bundle-Activator>
systems.dmx.geomaps.GeomapsPlugin
</Bundle-Activator>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>
package systems.dmx.geomaps;
public class GeoCoordinate {
// ---------------------------------------------------------------------------------------------- Instance Variables
public double lon, lat;
// ---------------------------------------------------------------------------------------------------- Constructors
public GeoCoordinate(double lon, double lat) {
this.lon = lon;
this.lat = lat;
}
/**
* Called by JAX-RS container to create a GeoCoordinate from a @QueryParam
*/
public GeoCoordinate(String lonLat) {
String[] str = lonLat.split(",");
this.lon = Double.valueOf(str[0]);
this.lat = Double.valueOf(str[1]);
}
// -------------------------------------------------------------------------------------------------- Public Methods
@Override
public String toString() {
return "long=" + lon + ", lat=" + lat;
}
}
package systems.dmx.geomaps;
import systems.dmx.core.JSONEnabled;
import systems.dmx.core.model.TopicModel;
import systems.dmx.core.model.topicmaps.ViewProps;
import systems.dmx.core.util.DMXUtils;
import org.codehaus.jettison.json.JSONObject;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Logger;
/**
* A geomap model: a collection of Geo Coordinate topics.
* <p>
* Features:
* - Serialization to JSON.
*/
public class Geomap implements Iterable<TopicModel>, JSONEnabled {
// ---------------------------------------------------------------------------------------------- Instance Variables
private TopicModel geomapTopic;
private ViewProps viewProps;
private Map<Long, TopicModel> geoCoords;
private Logger logger = Logger.getLogger(getClass().getName());
// ---------------------------------------------------------------------------------------------------- Constructors
Geomap(TopicModel geomapTopic, ViewProps viewProps, Map<Long, TopicModel> geoCoords) {
this.geomapTopic = geomapTopic;
this.viewProps = viewProps;
this.geoCoords = geoCoords;
}
// -------------------------------------------------------------------------------------------------- Public Methods
public long getId() {
return geomapTopic.getId();
}
// ### TODO: needed?
public boolean containsTopic(long geoCoordId) {
return geoCoords.get(geoCoordId) != null;
}
// ---
@Override
public JSONObject toJSON() {
try {
return new JSONObject()
.put("topic", geomapTopic.toJSON())
.put("viewProps", viewProps.toJSON())
.put("geoCoordTopics", DMXUtils.toJSONArray(geoCoords.values()));
} catch (Exception e) {
throw new RuntimeException("Serialization failed", e);
}
}
@Override
public Iterator<TopicModel> iterator() {
return geoCoords.values().iterator();
}
@Override
public String toString() {
return "geomap " + getId();
}
}
package systems.dmx.geomaps;
import systems.dmx.core.Topic;
import systems.dmx.core.model.topicmaps.ViewProps;
import systems.dmx.core.service.CoreService;
import systems.dmx.topicmaps.TopicmapType;
class GeomapType implements TopicmapType, GeomapsConstants {
@Override
public String getUri() {
return "dmx.geomaps.geomap";
}
@Override
public void initTopicmapState(Topic topicmapTopic, ViewProps viewProps, CoreService dmx) {
dmx.getModelFactory().newViewProps()
.put(PROP_LONGITUDE, 11.0) // default region is "Germany"
.put(PROP_LATITUDE, 51.0)
.put(PROP_ZOOM, 6.0)
.store(topicmapTopic);
}
}
package systems.dmx.geomaps;
public interface GeomapsConstants {
// topic types
static final String GEO_COORDINATE = "dmx.geomaps.geo_coordinate";
static final String GEO_COORDINATE_FACET = "dmx.geomaps.geo_coordinate_facet";
static final String LONGITUDE = "dmx.geomaps.longitude";
static final String LATITUDE = "dmx.geomaps.latitude";
// content assoc
static final String GEOMAP_CONTEXT = "dmx.geomaps.geomap_context";
static final String ROLE_TYPE_GEOMAP = "dmx.core.default";
static final String ROLE_TYPE_CONTENT = "dmx.core.default";
// geomap props
static final String PROP_LONGITUDE = "dmx.geomaps.longitude";
static final String PROP_LATITUDE = "dmx.geomaps.latitude";
static final String PROP_ZOOM = "dmx.geomaps.zoom";
}
package systems.dmx.geomaps;
import systems.dmx.core.Topic;
import java.util.List;
import java.util.concurrent.Callable;
public interface GeomapsService {
Geomap getGeomap(long geomapId);
/**
* Finds the domain topics (e.g. Persons, Organizations, Events) that correspond to a Geo Coordinate topic.
*/
List<Topic> getDomainTopics(long geoCoordId);
/**
* Returns the geo coordinate of a geo-facetted topic (e.g. an Address),
* or <code>null</code> if no geo coordinate is stored.
*
* @return the geo coordinate, or <code>null</code>.
*/
GeoCoordinate getGeoCoordinate(Topic geoTopic);
/**
* Returns the geo coordinate encoded in a Geo Coordinate topic.
*/
GeoCoordinate geoCoordinate(Topic geoCoordTopic);
/**
* Adds a Geo Coordinate topic to a geomap.
*/
void addCoordinateToGeomap(long geomapId, long geoCoordId);
void setGeomapState(long geomapId, double lon, double lat, double zoom);
/**
* Calculates the distance between 2 geo coordinates in kilometer.
*/
double getDistance(GeoCoordinate coord1, GeoCoordinate coord2);
// ---
/**
* Executes the passed codeblock and suppresses geocoding for Address topics created/updated while execution.
*
* @return the value returned by the codeblock.
*/
<V> V runWithoutGeocoding(Callable<V> callable) throws Exception;
}
<template>
<l-map class="dm5-geomap-renderer" :center.sync="center" :zoom.sync="zoom" :options="options">
<l-tile-layer :url="url"></l-tile-layer>
<l-marker v-for="topic in geoCoordTopics" :lat-lng="latLng(topic)" :key="topic.id"
@popupopen="popupOpen(topic.id, $event)">
<l-popup v-loading="loading">
<dm5-object-renderer v-if="domainTopic" :object="domainTopic" :quill-config="quillConfig">
</dm5-object-renderer>
<dm5-topic-list v-else :topics="domainTopics" no-sort-menu @topic-click="showDetails"></dm5-topic-list>
</l-popup>
</l-marker>
</l-map>
</template>
<script>
import { LMap, LTileLayer, LMarker, LPopup } from 'vue2-leaflet'
import 'leaflet/dist/leaflet.css'
import dm5 from 'dm5'
// stupid hack so that leaflet's images work after going through webpack
// https://github.com/PaulLeCam/react-leaflet/issues/255
delete L.Icon.Default.prototype._getIconUrl
L.Icon.Default.mergeOptions({
iconUrl: require('leaflet/dist/images/marker-icon.png'),
iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
shadowUrl: require('leaflet/dist/images/marker-shadow.png')
})
let popup
export default {
created () {
// console.log('dm5-geomap-renderer created')
},
mounted () {
// console.log('dm5-geomap-renderer mounted')
},
destroyed () {
// console.log('dm5-geomap-renderer destroyed')
},
props: {
quillConfig: Object
},
data () {
return {
// map
url: 'https://{s}.tile.osm.org/{z}/{x}/{y}.png',
options: {
zoomControl: false,
zoomSnap: 0,
attributionControl: false
},
// popup
domainTopic: undefined, // has precedence
domainTopics: [],
loading: undefined
}
},
computed: {
geomap () {
const geomap = this.$store.state.geomaps.geomap
// Note: the geomap might not be available yet as it is loaded *after* the topicmap renderer is installed
if (!geomap) {
// console.log('### Geomap not yet available')
return
}
return geomap
},
center: {
get () {
if (this.geomap) {
const viewProps = this.geomap.viewProps
return [
viewProps['dmx.geomaps.latitude'],
viewProps['dmx.geomaps.longitude']
]
}
},
set (center) {
// console.log('set center', center, this.center)
const viewProps = this.geomap.viewProps
viewProps['dmx.geomaps.latitude'] = center.lat
viewProps['dmx.geomaps.longitude'] = center.lng
this.storeGeomapState()
}
},
zoom: {
get () {
return this.geomap && this.geomap.viewProps['dmx.geomaps.zoom']
},
set (zoom) {
this.geomap.viewProps['dmx.geomaps.zoom'] = zoom
this.storeGeomapState()
}
},
geoCoordTopics () {
return this.geomap && this.geomap.geoCoordTopics
}
},
methods: {
popupOpen (geoCoordId, event) {
// console.log('popupOpen', geoCoordId, event.popup)
popup = event.popup
this.domainTopic = undefined // clear popup
this.domainTopics = [] // clear popup
this.loading = true
dm5.restClient.getDomainTopics(geoCoordId).then(topics => {
// console.log('domain topic', topic)
switch (topics.length) {
case 0:
throw Error(`no domain topics for geo coord topic ${geoCoordId}`)
case 1:
this.showDetails(topics[0]); break
default:
this.domainTopics = topics
this.loading = false
this.updatePopup()
}
})
},
showDetails (topic) {
this.loading = true
dm5.restClient.getTopic(topic.id, true, true).then(topic => {
this.domainTopic = topic
this.loading = false
this.updatePopup()
})
},
updatePopup () {
setTimeout(() => popup.update(), 300)
/* does not work
this.$nextTick()
.then(() => {
console.log('showDetail', popup)
popup.update()
})
*/
},
latLng (geoCoordTopic) {
// Note: Leaflet uses lat-lon order while most other tools (including DMX) and formats use lon-lat order.
// For exhaustive background information on this topic see https://macwright.org/lonlat/
return [
geoCoordTopic.children['dmx.geomaps.latitude'].value,
geoCoordTopic.children['dmx.geomaps.longitude'].value
]
},
storeGeomapState () {
this.$store.dispatch('_storeGeomapState', {
center: this.center,
zoom: this.zoom
})
}
},
components: {
LMap, LTileLayer, LMarker, LPopup,
'dm5-object-renderer': require('dm5-object-renderer').default,
'dm5-topic-list': require('dm5-topic-list').default
}
}
</script>
<style>
/* Leaflet overrides */
.leaflet-container {
font: unset;
}
.leaflet-popup-content {
min-width: 200px;
min-height: 42px; /* see --loading-spinner-size in element-ui/packages/theme-chalk/src/common/var.scss */
}
</style>
export default {
storeModule: require('./geomap-model').default,
comp: require('./components/dm5-geomap-renderer').default
}
import dm5 from 'dm5'
const actions = {
// Topicmap Panel protocol
fetchTopicmap (_, id) {
console.log('fetchTopicmap', id, '(geomap-model)')
return dm5.restClient.getGeomap(id)
},
renderTopicmap ({rootState}, {topicmap, writable, selection}) {
console.log('renderTopicmap', topicmap.viewProps)
rootState.geomaps.geomap = topicmap
},
// Geomap specific actions (module internal, dispatched from dm5-geomap-renderer component)
_storeGeomapState ({rootState}, {center, zoom}) {
// console.log('_storeGeomapState', center, zoom)
// update server
// if (_topicmapWritable) { // TODO
dm5.restClient.setGeomapState(rootState.geomaps.geomap.id, center[1], center[0], zoom)
// }
}
}
export default {
actions
}
const state = {
geomap: undefined // the rendered geomap (dm5.Geomap)
}
const actions = {
// WebSocket messages
_newGeoCoord (_, {geoCoordTopic}) {
console.log('_newGeoCoord', geoCoordTopic)
if (state.geomap) {
state.geomap.geoCoordTopics.push(geoCoordTopic)
} else {
// Note: if the geomap is not loaded no update is required
console.log('No geomap loaded')
}
}
}
export default {
state,
actions
}
export default {
storeModule: {
name: 'geomaps',
module: require('./geomaps').default
},
topicmapType: {
uri: 'dmx.geomaps.geomap',
name: "Geomap",
renderer: () => import('./dm5-geomap-renderer' /* webpackChunkName: "leaflet" */)
}
}
{
"topic_types": [
{
"value": "Longitude", // TODO: make it a prop?
"uri": "dmx.geomaps.longitude",
"dataTypeUri": "dmx.core.number"
},
{
"value": "Latitude", // TODO: make it a prop?
"uri": "dmx.geomaps.latitude",
"dataTypeUri": "dmx.core.number"
},
{
"value": "Geo Coordinate",
"uri": "dmx.geomaps.geo_coordinate",
"dataTypeUri": "dmx.core.value",
"compDefs": [
{
"childTypeUri": "dmx.geomaps.longitude",
"childCardinalityUri": "dmx.core.one",
"includeInLabel": true
},
{
"childTypeUri": "dmx.geomaps.latitude",
"childCardinalityUri": "dmx.core.one",
"includeInLabel": true
}
]
},
{
"value": "Geo Coordinate Facet",
"uri": "dmx.geomaps.geo_coordinate_facet",
"dataTypeUri": "dmx.core.identity",
"compDefs": [
{
"childTypeUri": "dmx.geomaps.geo_coordinate",
"childCardinalityUri": "dmx.core.one"
}
]
}
],
"assoc_types": [
{
"value": "Geomap Context",
"uri": "dmx.geomaps.geomap_context",
"dataTypeUri": "dmx.core.text"
}
]
}
......@@ -8,7 +8,7 @@
</div>
<div class="field">
<div class="field-label">Released</div>
Jan 10, 2020
Jan 13, 2020
</div>
<div class="field">
<div class="field-label">License</div>
......
......@@ -96,11 +96,6 @@
<artifactId>dmx-facets</artifactId>
<version>5.0-beta-7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>systems.dmx</groupId>
<artifactId>dmx-geomaps</artifactId>
<version>5.0-beta-7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>systems.dmx</groupId>
<artifactId>dmx-timestamps</artifactId>
......
......@@ -9,7 +9,7 @@ import 'font-awesome/css/font-awesome.css'
import './element-ui'
import './websocket'
console.log('[DMX] 2020/01/10')
console.log('[DMX] 2020/01/13')
// 1) Init dm5 library
// The dm5 library must be inited *before* the dm5-webclient component is instantiated.
......
......@@ -18,7 +18,6 @@ export default () => {
initPlugin(require('modules/dmx-typeeditor/src/main/js/plugin.js').default)
initPlugin(require('modules/dmx-datetime/src/main/js/plugin.js').default)
initPlugin(require('modules/dmx-help-menu/src/main/js/plugin.js').default)
initPlugin(require('modules/dmx-geomaps/src/main/js/plugin.js').default)
//
// while development add your plugins here
// initPlugin(require('modules-external/my-plugin/src/main/js/plugin.js').default)
......
......@@ -320,7 +320,6 @@
<module>modules/dmx-files</module>
<module>modules/dmx-accesscontrol</module>
<module>modules/dmx-facets</module>
<module>modules/dmx-geomaps</module>
<module>modules/dmx-timestamps</module>
<module>modules/dmx-caching</module>
<module>modules/dmx-config</module>
......@@ -392,7 +391,6 @@
<module>modules/dmx-files</module>
<module>modules/dmx-accesscontrol</module>
<module>modules/dmx-facets</module>
<module>modules/dmx-geomaps</module>
<module>modules/dmx-timestamps</module>
<module>modules/dmx-caching</module>
<module>modules/dmx-config</module>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment