diff --git a/src/App.css b/src/App.css index b0f08dddfc38b5c27752c025dbfe8113491b93d2..6bfc984c2940566cfc1c2197cf0f9b4c129da376 100644 --- a/src/App.css +++ b/src/App.css @@ -60,22 +60,22 @@ div.fade-main { } div.sticky { - position: fixed; - top: 0px; - right: 0px; - height: 100px; - width: 100px; - margin-right: 150px; + position: fixed; + top: 0px; + right: 0px; + height: 100px; + width: 100px; + margin-right: 150px; } .close { - position: fixed; - color: #f1f1f1; - height: 85px; - font-size: 100px; - font-weight: bold; - transition: transform 0.4s ease-in-out; - line-height: 70%; + position: fixed; + color: #f1f1f1; + height: 85px; + font-size: 100px; + font-weight: bold; + transition: transform 0.4s ease-in-out; + line-height: 70%; } .close:hover, @@ -138,3 +138,45 @@ div.login button:hover { background-color: darkblue; cursor: pointer; } + +/* Editing text button in the toolbar */ +.leaflet-draw-toolbar .leaflet-draw-draw-textbox { + background-image: url("icons/button-textbox.png"); + background-size: 30px 30px; +} + +/* Editing tooltips */ +.leaflet-tooltip { + font-size: 18px; + /* Overriding tooltip layout by making it invisible */ + background-color: transparent; + box-shadow: none; + border: none; + padding: 0; +} + +/* remove the small triangle on tooltip */ +.leaflet-tooltip-bottom:before { + border: 0; +} + +/* Editing editable tooltips */ +.editable { + cursor: text; /* the cursor icon doesn't change by default when hovering on top of the text; overriding */ + min-width: 154px; + min-height: 18px; + color: #fff; + font-weight: bold; + /* text borders */ + text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, + 1px 1px 0 #000; +} + +/* placeholder text for tooltip */ +[contenteditable="true"]:empty:before { + content: attr(placeholder); + display: block; /* For Firefox */ + color: #777; + text-shadow: none; + font-weight: normal; +} diff --git a/src/components/DrawTools.js b/src/components/DrawTools.js index 2f21335ac906617b685820c727f083aab64944fb..2f36baf7e6d506eaf87a140fbd8366c1129ae7d0 100644 --- a/src/components/DrawTools.js +++ b/src/components/DrawTools.js @@ -1,6 +1,69 @@ import React, { Component } from "react"; import { EditControl } from "react-leaflet-draw"; +<<<<<<< src/components/DrawTools.js import { FeatureGroup } from "react-leaflet"; +======= +import L from "leaflet"; +import "leaflet-draw"; +import { FeatureGroup } from "react-leaflet"; + +// class for text field +L.Draw.MarkerTextBox = L.Draw.Marker.extend({ + options: { + icon: L.divIcon({ + className: "", // empty class to override default styling + iconSize: [20, 20], + iconAnchor: [10, 20] + }), + repeatMode: false, + interactive: true + }, + initialize: function(map, options) { + this.type = "textbox"; // important to have a unique type, so that it won't get mixed up with other elements + this.featureTypeCode = "textbox"; + L.Draw.Feature.prototype.initialize.call(this, map, options); + } +}); + +// Overriding default toolbar +// Just adding one new button though lol +L.DrawToolbar.include({ + getModeHandlers: function(map) { + return [ + { + enabled: this.options.polyline, + handler: new L.Draw.Polyline(map, this.options.polyline), + title: L.drawLocal.draw.toolbar.buttons.polyline + }, + { + enabled: this.options.polygon, + handler: new L.Draw.Polygon(map, this.options.polygon), + title: L.drawLocal.draw.toolbar.buttons.polygon + }, + { + enabled: this.options.rectangle, + handler: new L.Draw.Rectangle(map, this.options.rectangle), + title: L.drawLocal.draw.toolbar.buttons.rectangle + }, + { + enabled: this.options.circle, + handler: new L.Draw.Circle(map, this.options.circle), + title: L.drawLocal.draw.toolbar.buttons.circle + }, + { + enabled: this.options.marker, + handler: new L.Draw.Marker(map, this.options.marker), + title: L.drawLocal.draw.toolbar.buttons.marker + }, + { + enabled: this.options.marker, + handler: new L.Draw.MarkerTextBox(map, this.options.marker), + title: "Write text" + } + ]; + } +}); +>>>>>>> src/components/DrawTools.js class DrawTools extends Component { constructor(props) { @@ -11,6 +74,7 @@ class DrawTools extends Component { } _onCreated = e => { +<<<<<<< src/components/DrawTools.js let type = e.layerType; // from the example; isn't used right now, but may be relevant in the future let layer = e.layer; this.makeGeoJSON(e.layer); @@ -23,6 +87,63 @@ class DrawTools extends Component { newGeoJSONAll.push(geoJSON); this.setState({ geoJSONAll: newGeoJSONAll }); console.log(JSON.stringify(geoJSON, null, 4)); // printing GeoJSON data of the previous object create +======= + // check if a drawn polyline has just one point in it + if (e.layerType === "polyline" && e.layer.getLatLngs().length === 1) { + e.layer.remove(); + return; + } + + if (e.layerType === "textbox") { + // have to create tooltip as a DOM element to allow text selecting. maybe + let tooltip = L.DomUtil.create("div", "editable"); + tooltip.innerHTML = + '<div contenteditable="true" placeholder="Click here and type"></div>'; + + e.layer.bindTooltip(tooltip, { + permanent: true, + direction: "bottom", + interactive: true + }); + + // disable dragging when cursor is over marker (tooltip) + // clicking on tooltip fires the marker's click handler, hence e.layer.on + e.layer.on("mouseover", function() { + e.layer._map.dragging.disable(); + }); + + // enable dragging again when cursor is out of marker (tooltip) + e.layer.on("mouseout", function() { + e.layer._map.dragging.enable(); + }); + + // show placeholder text again upon emptying textbox + e.layer.on("keyup", function() { + // when the text area is emptied, a <br> appears + // manually removing it so that the placeholder text can show + if ( + tooltip.innerHTML === + '<div placeholder="Click here and type" contenteditable="true"><br></div>' || + tooltip.innerHTML === + '<div placeholder="Click here and type" contenteditable="true"><div><br></div></div>' + ) { + tooltip.innerHTML = + '<div placeholder="Click here and type" contenteditable="true"></div>'; + } + }); + } // end if (e.layerType === "textbox") + + // turning layer data to GeoJSON + this.makeGeoJSON(e.layer); + }; // end _onCreated + + makeGeoJSON = e => { + let geoJSON = e.toGeoJSON(); + let newGeoJSONAll = this.state.geoJSONAll; + newGeoJSONAll.push(geoJSON); // can't do +=, need to use push function + console.log(JSON.stringify(newGeoJSONAll, null, 4)); + this.setState({ geoJSONAll: newGeoJSONAll }); +>>>>>>> src/components/DrawTools.js }; render() { @@ -34,6 +155,7 @@ class DrawTools extends Component { onCreated={this._onCreated} draw={{ circle: { +<<<<<<< src/components/DrawTools.js repeatMode: false, // allows using the tool again after finishing the previous shape. turned off here shapeOptions: { color: "#f9f10c", @@ -42,6 +164,16 @@ class DrawTools extends Component { }, rectangle: { repeatMode: false +======= + repeatMode: true, // allows using the tool again after finishing the previous shape + shapeOptions: { + color: "#f9f10c", + opacity: 1 // affects the outline only. for some reason it wasn't at full opacity, so this is needed for more clarity + } + }, + rectangle: { + repeatMode: true +>>>>>>> src/components/DrawTools.js }, polygon: { repeatMode: true, @@ -52,18 +184,30 @@ class DrawTools extends Component { }, shapeOptions: { color: "#ed2572", +<<<<<<< src/components/DrawTools.js opacity: 100 +======= + opacity: 1 +>>>>>>> src/components/DrawTools.js } }, polyline: { repeatMode: true, shapeOptions: { color: "#ed2572", +<<<<<<< src/components/DrawTools.js opacity: 100 } }, marker: { repeatMode: true +======= + opacity: 1 + } + }, + marker: { + repeatMode: false +>>>>>>> src/components/DrawTools.js }, circlemarker: false }} diff --git a/src/components/UserMap.js b/src/components/UserMap.js index 52cce7ac28be2f1bbaa3a8aaeafd523e5b047cb3..4b3e690ea038c66268066abdda38bedb7a22cdfa 100644 --- a/src/components/UserMap.js +++ b/src/components/UserMap.js @@ -1,54 +1,52 @@ -import React, {Component} from 'react'; -import { - Map, - TileLayer, - ZoomControl, - Marker, - Popup -} from 'react-leaflet' -import DrawTools from './DrawTools.js' +import React, { Component } from "react"; +import { Map, TileLayer, ZoomControl, Marker, Popup } from "react-leaflet"; +import L from "leaflet"; +import DrawTools from "./DrawTools.js"; class UserMap extends Component { - constructor(props){ + constructor(props) { super(props); this.state = { ownLat: null, ownLng: null, - mapUrl: 'https://tiles.kartat.kapsi.fi/taustakartta/{z}/{x}/{y}.jpg' - } + mapUrl: "https://tiles.kartat.kapsi.fi/taustakartta/{z}/{x}/{y}.jpg" + }; this.watchPositionId = null; } - componentDidMount(){ - this.getCurrentPosition((position) => { + componentDidMount() { + this.getCurrentPosition(position => { this.setCurrentPosition(position); }); } - componentWillUnmount(){ - if(this.watchPositionId != null){ + componentWillUnmount() { + if (this.watchPositionId != null) { navigator.geolocation.clearWatch(this.watchPositionId); } } - setCurrentPosition(position){ + setCurrentPosition(position) { this.setState({ ownLat: position.coords.latitude, - ownLng: position.coords.longitude, + ownLng: position.coords.longitude }); } - getCurrentPosition(callback){ - if(!navigator.geolocation){ + getCurrentPosition(callback) { + if (!navigator.geolocation) { console.log("Can't get geolocation :/"); - } - else{ + } else { // Position tracking options const options = { enableHighAccuracy: true, timeout: 30000, maximumAge: 0 + }; + + if (this.watchPositionId != null) { + navigator.geolocation.clearWatch(this.watchPositionId); } if(this.watchPositionId != null){navigator.geolocation.clearWatch(this.watchPositionId);} @@ -68,7 +66,7 @@ class UserMap extends Component { } } - positionToGeoJSON(position){ + positionToGeoJSON(position) { let geoJSON = { type: "Feature", properties: {}, @@ -76,11 +74,15 @@ class UserMap extends Component { type: "Point", coordinates: [position.coords.longitude, position.coords.latitude] } - } + }; return JSON.stringify(geoJSON); } + testers = asd => { + console.log(asd.target.getZoom()); + }; + render() { return ( <Map @@ -94,21 +96,25 @@ class UserMap extends Component { attribution='© <a href="https://www.maanmittauslaitos.fi/">Maanmittauslaitos</a>' url={this.props.mapUrl} /> - <ZoomControl position='topright' /> - <DrawTools position={this.props.position} /> + + <ZoomControl position="topright" /> + <DrawTools position={this.props.position} /> <Marker position={this.props.position}> <Popup> Se on perjantai, my dudes <br /> </Popup> </Marker> - {this.state.ownLat !== null && <Marker position={[this.state.ownLat, this.state.ownLng]}> - <Popup> - User's real position.<br /> - </Popup> - </Marker>} + {this.state.ownLat !== null && ( + <Marker position={[this.state.ownLat, this.state.ownLng]}> + <Popup> + User's real position. + <br /> + </Popup> + </Marker> + )} </Map> ); } } -export default UserMap; \ No newline at end of file +export default UserMap; diff --git a/src/icons/button-textbox.png b/src/icons/button-textbox.png new file mode 100644 index 0000000000000000000000000000000000000000..e36a2872bdf8f68df996d35159335a77211ead7a Binary files /dev/null and b/src/icons/button-textbox.png differ diff --git a/src/icons/nil.png b/src/icons/nil.png new file mode 100644 index 0000000000000000000000000000000000000000..ae058ee7bffad41634a20cd463fc94219f0de69b Binary files /dev/null and b/src/icons/nil.png differ