Skip to content

Commit

Permalink
Added a marker that shows where the click event occured:
Browse files Browse the repository at this point in the history
- Currently the marker is hard-coded (never a good solution.
- In order to make it a setting we need to differentiate it from the current Infoclick settings. Right now there is no way to set a marker for click event. The marker that exists in Admin is for actually marking the clicked feature (if it is a Point feature). We want to keep this setting too, and it's possible that we want different indicators for those two points (one for the 'clicked here' marker and another one to actually mark a selected feature).
- Also, I tried to give some reasonable properties to the vector layer needed for this. Please see #883 for more info.
  • Loading branch information
jacobwod committed Mar 25, 2022
1 parent 9819e47 commit 73bd8d5
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 6 deletions.
5 changes: 4 additions & 1 deletion new-client/src/components/MapClickViewer/MapClickViewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ const MapClickViewer = (props) => {

// Remove highlight from any highlighted features in map
appModel.highlight(false);
}, [appModel]);

// Tell the MapClickModel to remove the clicked marker
globalObserver.publish("mapClick.removeMarker");
}, [appModel, globalObserver]);

// Subscribe to events on global observer
useEffect(() => {
Expand Down
2 changes: 1 addition & 1 deletion new-client/src/models/AppModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ class AppModel {
config.tools.find((t) => t.type === "infoclick")?.options
?.useNewInfoclick === true;
if (useNewInfoclick) {
const mapClickModel = new MapClickModel(this.map);
const mapClickModel = new MapClickModel(this.map, this.globalObserver);

mapClickModel.bindMapClick((featureCollections) => {
const featureCollectionsToBeHandledByMapClickViewer =
Expand Down
62 changes: 58 additions & 4 deletions new-client/src/models/MapClickModel.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,37 @@
import { hfetch } from "utils/FetchWrapper";

import GeoJSON from "ol/format/GeoJSON";
import WMSGetFeatureInfo from "ol/format/WMSGetFeatureInfo";

import TileLayer from "ol/layer/Tile";
import ImageLayer from "ol/layer/Image";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import { Style, Icon } from "ol/style";
import Feature from "ol/Feature";
import Point from "ol/geom/Point";

export default class MapClickModel {
constructor(map) {
console.log("Creating new MapClickModel");
constructor(map, globalObserver) {
this.map = map;
this.globalObserver = globalObserver;

// Setup the parsers once and for all
this.geoJsonParser = new GeoJSON();
this.wmsGetFeatureInfoParser = new WMSGetFeatureInfo();

// Prepare a source and layer so that we can put
// a marker in map when user clicks a coordinate
this.source = new VectorSource();
this.vector = new VectorLayer({
source: this.source,
name: "MapClickModel", // #883, should we call the layers the same as models that create them?
type: "system", // #883: "system" for the core system layers, to differentiate from "normal" WMS/Vector/etc layers?
zIndex: "1000", // We want this to stay on top of other layers
});
this.map.addLayer(this.vector);

// Register a listener for removing the clicked marker
this.globalObserver.subscribe("mapClick.removeMarker", this.#removeMarker);
}

/**
Expand All @@ -24,7 +42,6 @@ export default class MapClickModel {
* @memberof MapClickModel
*/
async bindMapClick(callback) {
console.log("Registering map.onSingleClick");
this.map.on(
"singleclick",
(e) => this.map.clickLock.size === 0 && this.#handleClick(e, callback)
Expand Down Expand Up @@ -318,12 +335,49 @@ export default class MapClickModel {

// Invoke the callback, supply the results.
callback(decoratedFeatureCollections);

// If we've got any results, let's highlight the clicked
// pixel by placing a marker in that coordinate.
decoratedFeatureCollections.length > 0
? this.#addMarker(this.map.getCoordinateFromPixel(e.pixel))
: this.#removeMarker();
} catch (error) {
console.error("Oops: ", error);
document.querySelector("body").style.cursor = "initial";
}
}

/**
* @summary Removes any previous markers and adds a new one to the given coordinates.
* @memberof CoordinatesModel
*/
#addMarker = (coordinates) => {
// Prepare the feature
const feature = new Feature({
geometry: new Point(coordinates),
});

// Style it with a nice icon
const styleMarker = new Style({
image: new Icon({
anchor: [0.5, 1],
scale: 0.15,
src: "marker.png",
}),
});
feature.setStyle(styleMarker);

// Remove any previous markers
this.#removeMarker();

// Add the new marker
this.source.addFeature(feature);
};

#removeMarker = () => {
this.vector.getSource().clear();
};

#decorateFeaturesInCollections(featureCollections) {
/**
* @summary Try to prepare a nice label for the list view.
Expand Down

0 comments on commit 73bd8d5

Please sign in to comment.