Skip to content

Commit

Permalink
Remove Open Layers, migrate to Leaflet JS (#71)
Browse files Browse the repository at this point in the history
* Basic migration to LeafletJS started.

* Remove bloodhound, add leaflet nominatim search. Change all typeahead calls to async AJAX calls.

* Almost done with convertig to Leaflet.

* Enable double click marker additions.

* Remove Open layers for good. Add documentation for new features.
  • Loading branch information
mkalus authored Aug 27, 2021
1 parent efd4141 commit c155d34
Show file tree
Hide file tree
Showing 30 changed files with 2,253 additions and 1,464 deletions.
35 changes: 30 additions & 5 deletions src/main/java/org/segrada/controller/MainController.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.google.inject.Inject;
import com.google.inject.servlet.RequestScoped;
import com.sun.jersey.api.view.Viewable;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.segrada.service.ConfigService;
import org.segrada.servlet.SegradaUpdateChecker;
import org.segrada.session.ApplicationSettings;
Expand Down Expand Up @@ -53,17 +55,40 @@ public Viewable index() {
String requireLogin = applicationSettings.getSetting("requireLogin");
boolean showLogout = requireLogin != null && !requireLogin.isEmpty() && requireLogin.equalsIgnoreCase("true");

// map engine defined in settings
String mapEngine = applicationSettings.getSetting("map.engine");
if (mapEngine == null) mapEngine = "ol"; // open layers as default

// create model map
Map<String, Object> model = new HashMap<>();
model.put("version", SegradaUpdateChecker.currentVersion);
model.put("versionUpdate", versionUpdate);
model.put("showLogout", showLogout);
model.put("mapEngine", mapEngine);

try {
model.put("mapSettings", defineMapSettings());
} catch (JSONException e) {
// ignore silently
}

return new Viewable("home", model);
}

// define map settings as JSON string
protected String defineMapSettings() throws JSONException {
// define map settings
JSONObject mapSettings = new JSONObject();

// from settings
mapSettings.put("provider", applicationSettings.getSettingOrDefault("map.provider", "Stamen.TerrainBackground"));
mapSettings.put("zoom", applicationSettings.getSettingAsInteger("map.defaultZoom", 13));
mapSettings.put("lat", applicationSettings.getSettingAsInteger("map.defaultLat", 0));
mapSettings.put("lng", applicationSettings.getSettingAsInteger("map.defaultLng", 0));

// options
JSONObject mapOptions = new JSONObject();
mapSettings.put("options", mapOptions);

for (Map.Entry<String, String> entry : applicationSettings.getAllSettingsStartingWith("map.options.").entrySet()) {
mapOptions.put(entry.getKey(), entry.getValue());
}

return mapSettings.toString();
}
}
31 changes: 31 additions & 0 deletions src/main/java/org/segrada/session/ApplicationSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Map;

/**
* Copyright 2015-2021 Maximilian Kalus [segrada@auxnet.de]
Expand All @@ -28,6 +29,36 @@ public interface ApplicationSettings {
*/
@Nullable String getSetting(String key);

/**
* retrieve a setting from settings - if empty, get default
* @param key to look for
* @return value retrieved or default value
*/
@Nullable String getSettingOrDefault(String key, String defaultValue);

/**
* retrieve a setting from settings - parse to int
* @param key to look for
* @param defaultValue value retrieved or default value
* @return value retrieved or default value
*/
int getSettingAsInteger(String key, int defaultValue);

/**
* retrieve a setting from settings - parse to double
* @param key to look for
* @param defaultValue value retrieved or default value
* @return value retrieved or default value
*/
double getSettingAsDouble(String key, double defaultValue);

/**
* retrieve all settings starting with a certain key - this key is also cut from the settings
* @param key part to look for
* @return list of matches
*/
Map<String, String> getAllSettingsStartingWith(String key);

/**
* retrieve a setting from the settings - with default value
* @param key to look for
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.segrada.session;

import com.google.inject.Singleton;
import org.codehaus.jettison.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -60,7 +61,11 @@ public class ApplicationSettingsProperties implements ApplicationSettings {
buildMap.put("SEGRADA_SOLR_FIELD_TAG", "solr.field_tag");
buildMap.put("SEGRADA_SOLR_FIELD_COLOR", "solr.field_color");
buildMap.put("SEGRADA_SOLR_FIELD_ICON", "solr.icon");
buildMap.put("SEGRADA_MAP_ENGINE", "map.engine");
buildMap.put("SEGRADA_MAP_DEFAULT_ZOOM", "map.defaultZoom");
buildMap.put("SEGRADA_MAP_DEFAULT_LAT", "map.defaultLat");
buildMap.put("SEGRADA_MAP_DEFAULT_LNG", "map.defaultLng");
buildMap.put("SEGRADA_MAP_PROVIDER", "map.provider");
// map options are handled below - as JSON string
buildMap.put("SEGRADA_BINARY_DATA_SERVICE", "binaryDataService");
buildMap.put("SEGRADA_HADOOP_CONFIGURATION_FILES", "binaryDataService.hadoop.configurationFiles");
buildMap.put("SEGRADA_HADOOP_FS_DEFAULT_FS", "binaryDataService.hadoop.fs.defaultFS");
Expand Down Expand Up @@ -96,7 +101,7 @@ public ApplicationSettingsProperties() {
System.exit(-1);
}

// now overwrite propeties with those defined as system variables
// now overwrite properties with those defined as system variables
Map<String, String> var = System.getenv();
for (Map.Entry<String, String> envToPropEntry : environmentToProperty.entrySet()) {
if (var.containsKey(envToPropEntry.getKey())) {
Expand All @@ -112,6 +117,23 @@ public ApplicationSettingsProperties() {
}
}

// map options as JSON string
if (var.containsKey("SEGRADA_MAP_OPTIONS")) {
String value = var.get("SEGRADA_MAP_OPTIONS");

try {
JSONObject jsonSettings = new JSONObject(value);

Iterator it = jsonSettings.keys();
while (it.hasNext()) {
String key = (String) it.next();
settings.setProperty("map.options." + key, jsonSettings.getString(key));
}
} catch (Exception e) {
logger.error("Could not read SEGRADA_MAP_OPTIONS: ", e);
}
}

// now overwrite properties with those defined via command line
Properties env = System.getProperties();

Expand Down Expand Up @@ -145,6 +167,68 @@ public String getSetting(String key) {
return settings.getProperty(key);
}

/**
* retrieve a setting from settings - if empty, get default
* @param key to look for
* @return value retrieved or default value
*/
@Nullable
@Override
public String getSettingOrDefault(String key, String defaultValue) {
String back = getSetting(key);
if (back == null || back.isEmpty()) return defaultValue;
return back;
}

/**
* retrieve a setting from settings - parse to int
* @param key to look for
* @param defaultValue value retrieved or default value
* @return value retrieved or default value
*/
@Override
public int getSettingAsInteger(String key, int defaultValue) {
String back = getSetting(key);
if (back == null || back.isEmpty()) return defaultValue;

try {
return Integer.parseInt(back);
} catch (Exception e) {
return defaultValue;
}
}

/**
* retrieve a setting from settings - parse to double
* @param key to look for
* @param defaultValue value retrieved or default value
* @return value retrieved or default value
*/
@Override
public double getSettingAsDouble(String key, double defaultValue) {
String back = getSetting(key);
if (back == null || back.isEmpty()) return defaultValue;

try {
return Double.parseDouble(back);
} catch (Exception e) {
return defaultValue;
}
}

@Override
public Map<String, String> getAllSettingsStartingWith(String key) {
Map<String, String> filteredSettings = new HashMap<>();

for (String propertyKey : settings.stringPropertyNames()) {
if (propertyKey.startsWith(key)) {
filteredSettings.put(propertyKey.substring(key.length()), settings.get(propertyKey).toString());
}
}

return filteredSettings;
}

@Nullable
@Override
public String getSetting(String key, @Nullable String defaultValue) {
Expand Down
15 changes: 13 additions & 2 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,19 @@ lucene.analyzer=org.segrada.search.lucene.LuceneSegradaAnalyzer
# Embedded Jetty settings
server.port=8080
server.context=/
# Settings for map rendering (ol is the only possible setting right now)
map.engine = ol
# Leaflet settings
# Default zoom level for Leaflet maps (maps with markers will zoom to bounds)
map.defaultZoom = 1
# Default coordinates for Leaflet maps (maps with markers will pan to markers)
map.defaultLat = 0
map.defaultLng = 0
# Map provider of the base map (see https://github.com/leaflet-extras/leaflet-providers) - for Stamen, try
# Stamen.TerrainBackground or Stamen.Terrain
# view a list of possible providers: http://leaflet-extras.github.io/leaflet-providers/preview/index.html
map.provider = Stamen.TerrainBackground
# Options that are passed to Provider Settings - see https://github.com/leaflet-extras/leaflet-providers
# These options use the pattern: map.option.<key> = <value>
# map.options.apikey = [insert your API key here]
# Class to load for BinaryDataService, possible values: org.segrada.service.binarydata.BinaryDataServiceFile
# and org.segrada.service.binarydata.BinaryDataServiceHadoop
binaryDataService=org.segrada.service.binarydata.BinaryDataServiceFile
Expand Down
14 changes: 12 additions & 2 deletions src/main/resources/documentation/de/command_line_options.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ Beispiel:
* `allowAnonymous` Anonymen Login erlauben, falls requireLogin wahr ist (Voreinstellung: false)
* `uploads.storage` Art des Zwischenspeichers für hochgeladene Dateien, MEMORY oder FILE (Voreinstellung: MEMORY)
* `uploads.maximum_upload_size` Maximum upload size (Voreinstellung: 52428800 aka 50 MB)
* `map.engine` Verwendeter Kartenserver (Voreinstellung: ol für OpenLayers, keine weiteren Optionen im Moment)
* `map.defaultZoom` Zoom-Ebene für Karten ohne Marker (Voreinstellung: 1, Werte zwischen 0 und 20)
* `map.defaultLat` Voreinstellung Breitengrad (Voreinstellung: 0)
* `map.defaultLng` Voreinstellung Längengrad (Voreinstellung: 0)
* `map.provider` Karten-Provider wie in [Leaflet-Providers](https://github.com/leaflet-extras/leaflet-providers) definiert (Voreinstellung: Stamen.TerrainBackground), [Beispiele](http://leaflet-extras.github.io/leaflet-providers/preview/index.html)
* `map.options.[schlüssel]` Zusätzliche Optionen für Karten-Provider (z.B. API-Schlüssel `map.options.apiKey = 123456`).
* `binaryDataService` Verwendeter Dateidienst, für Hadoop org.segrada.service.binarydata.BinaryDataServiceHadoop setzen (Voreinstellung: org.segrada.service.binarydata.BinaryDataServiceFile)
* `binaryDataService.hadoop.configurationFiles` Hadoop Optionale Konfigurationsdateien (Komma-getrennt, Vorsteinstellung: leer)
* `binaryDataService.hadoop.fs.defaultFS` Hadoop Server-URI (Voreinstellung: hdfs://localhost:9000/)
Expand All @@ -48,12 +52,14 @@ Beispiel Windows:

set SEGRADA_SAVE_PATH=C:\path\to\segrada
set SEGRADA_ORIENTDB_URL=plocal:C:\path\to\segrada\db
set SEGRADA_MAP_PROVIDER=OpenStreetMap.Mapnik
java -jar segrada-1.0-SNAPSHOT.jar

Beispiel Linux/OS X:

SEGRADA_SAVE_PATH=/home/myhome/devel/Segrada/segrada_data \
SEGRADA_ORIENTDB_URL=plocal:/home/myhome/Segrada/Java/segrada_data/db \
SEGRADA_MAP_PROVIDER=OpenStreetMap.Mapnik \
java -jar segrada-1.0-SNAPSHOT.jar

Umgebungsvariablen und ihre Äquivalente von oben:
Expand All @@ -79,7 +85,11 @@ Umgebungsvariablen und ihre Äquivalente von oben:
* `SEGRADA_SOLR_FIELD_TAG` -> `solr.field_tag`
* `SEGRADA_SOLR_FIELD_COLOR` -> `solr.field_color`
* `SEGRADA_SOLR_FIELD_ICON` -> `solr.field_icon`
* `SEGRADA_MAP_ENGINE` -> `map.engine`
* `SEGRADA_MAP_DEFAULT_ZOOM` -> `map.defaultZoom"`
* `SEGRADA_MAP_DEFAULT_LAT` -> `map.defaultLat"`
* `SEGRADA_MAP_DEFAULT_LNG` -> `map.defaultLng"`
* `SEGRADA_MAP_PROVIDER` -> `map.provider"`
* `SEGRADA_MAP_OPTIONS` -> Falls dies ein JSON-Objekt ist (als Zeichenkette), wird der Wert in korrekte Karten-Optionen umgewandelt
* `SEGRADA_BINARY_DATA_SERVICE` -> `binaryDataService`
* `SEGRADA_HADOOP_CONFIGURATION_FILES` -> `binaryDataService.hadoop.configurationFiles`
* `SEGRADA_HADOOP_FS_DEFAULT_FS` -> `binaryDataService.hadoop.fs.defaultFS`
Expand Down
12 changes: 10 additions & 2 deletions src/main/resources/documentation/en/command_line_options.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ Example:
* `allowAnonymous` Allow anonymous login, if requireLogin is true (default: false)
* `uploads.storage` Type of storage used when uploading files, MEMORY or FILE (default: MEMORY)
* `uploads.maximum_upload_size` Maximum upload size (default: 52428800 aka 50 MB)
* `map.engine` Map engine to use (default: ol for OpenLayers, no other options yet)
* `map.defaultZoom` Zoom level of map without markers (default: 1, can be 0-20)
* `map.defaultLat` Default latitude of map (default: 0)
* `map.defaultLng` Default longitude of map (default: 0)
* `map.provider` Map provider as per definitions of [Leaflet-Providers](https://github.com/leaflet-extras/leaflet-providers) (default: Stamen.TerrainBackground), see [preview](http://leaflet-extras.github.io/leaflet-providers/preview/index.html) for examples.
* `map.options.[key]` Additional options for map providers (e.g. API key `map.options.apiKey = 123456`).
* `binaryDataService` File service use, for Hadoop, set org.segrada.service.binarydata.BinaryDataServiceHadoop (default: org.segrada.service.binarydata.BinaryDataServiceFile)
* `binaryDataService.hadoop.configurationFiles` Hadoop optional configuration file (comma separated, default: empty)
* `binaryDataService.hadoop.fs.defaultFS` Hadoop server URI (default: hdfs://localhost:9000/)
Expand Down Expand Up @@ -80,7 +84,11 @@ Mappings to command line parameters above:
* `SEGRADA_SOLR_FIELD_TAG` -> `solr.field_tag`
* `SEGRADA_SOLR_FIELD_COLOR` -> `solr.field_color`
* `SEGRADA_SOLR_FIELD_ICON` -> `solr.field_icon`
* `SEGRADA_MAP_ENGINE` -> `map.engine`
* `SEGRADA_MAP_DEFAULT_ZOOM` -> `map.defaultZoom"`
* `SEGRADA_MAP_DEFAULT_LAT` -> `map.defaultLat"`
* `SEGRADA_MAP_DEFAULT_LNG` -> `map.defaultLng"`
* `SEGRADA_MAP_PROVIDER` -> `map.provider"`
* `SEGRADA_MAP_OPTIONS` -> If this is a JSON object (as string), it will parse the key/values and set the map options
* `SEGRADA_BINARY_DATA_SERVICE` -> `binaryDataService`
* `SEGRADA_HADOOP_CONFIGURATION_FILES` -> `binaryDataService.hadoop.configurationFiles`
* `SEGRADA_HADOOP_FS_DEFAULT_FS` -> `binaryDataService.hadoop.fs.defaultFS`
Expand Down
37 changes: 18 additions & 19 deletions src/main/resources/js/segrada.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,38 @@ function escapeHTML(myString) {
* Substring matcher for remote searches for nodes
* @param searchUrl
*/
var genericMatcher = function(searchUrl) {
return function findMatches(q, cb) {
var response = $.ajax({
url: searchUrl + encodeURIComponent(q),
async: false
const genericMatcher = function(searchUrl) {
return function findMatches(q, _, cb) {
const response = $.ajax({
url: searchUrl + encodeURIComponent(q)
}).done(function (data) {
cb(data);
});

cb(JSON.parse(response.responseText));
}
};


/**
* Substring matcher for remote searches for nodes
*/
var nodeMatcher = function() {
return function findMatches(q, cb) {
var searchUrl = urlSegradaNodeSearch + encodeURIComponent(q);
const nodeMatcher = function() {
return function findMatches(q, _, cb) {
let searchUrl = urlSegradaNodeSearch + encodeURIComponent(q);

// get current textField
var textField = $(".sg-node-search").filter(":focus");
var relationTypeSelect = $("#" + textField.attr('data-select-id') + ' option').filter(":selected");
var contraintIds = relationTypeSelect.attr(textField.attr('data-attr'));
const textField = $(".sg-node-search").filter(":focus");
const relationTypeSelect = $("#" + textField.attr('data-select-id') + ' option').filter(":selected");
const contraintIds = relationTypeSelect.attr(textField.attr('data-attr'));
if (contraintIds != null && contraintIds.length > 0) {
// add list of ids
searchUrl += '&tags=' + encodeURIComponent(contraintIds);
}

var response = $.ajax({
url: searchUrl,
async: false
const response = $.ajax({
url: searchUrl
}).done(function (data) {
cb(data);
});

cb(JSON.parse(response.responseText));
}
};

Expand Down Expand Up @@ -470,7 +468,8 @@ function escapeHTML(myString) {
limit: 25,
displayKey: 'title',
valueKey: 'title',
source: genericMatcher(urlSegradaTagSearch)
source: genericMatcher(urlSegradaTagSearch),
async: true
}
});

Expand Down
Loading

0 comments on commit c155d34

Please sign in to comment.