React: Leaflet Markers

This entry is part 9 of 9 in the series React: Leaflet

In this tutorial I will demonstrate how to add a marker to the map. Refer to the documentation for more information.

Before We Begin:

Text:

LayerGroup onAdd Method

//Define the marker. Since this is text based their is no icon but instead a divIcon
this.textMarker = L.marker([20.5, -0.09],{
	icon: L.divIcon({
		iconSize: [100,16],
		iconAnchor: [22, 30],
		className: "",
	}), 
	zIndexOffset: 75,
});

//Sets the text
this.textMarker.options.icon.options.html = "This is my text";

//Adds the text marker to the layer
this.addLayer(this.textMarker);

LayerGroup onRemove Method

//Remove the text marker you just added
this.removeLayer(this.textMarker);

Results: Now you will see as you turn the layer on and off from the context menu the text will show or hide.

Icon:

Import Image:

import myImagefrom "../images/myImage.png";

Create Icon/Marker onAdd Method

//Define the icon you will be using
var myIcon = L.icon({
	iconUrl: myImage,
	iconSize:     [75, 75], // size of the icon
	iconAnchor:   [22, 94], // point of the icon which will correspond to marker's location
});

//Define the icon based marker
this.marker = L.marker([20.5, -40.09],{
	icon: myIcon,
	opacity: 0.7,
	zIndexOffset: 30
 });

//Adds the icon marker to the layer
this.addLayer(this.marker);

onRemove Method

//Remove the marker you just added
this.removeLayer(this.marker);

Results: Now you will see as you turn the layer on and off from the context menu the icon will show or hide.

Set Latitude/Longitude:

You can set the latitude and longitude in one of two ways.

//Set the latitude and longitude

//Method 1:
L.marker([20.5, -0.09])

//Method 2:
this.textMarker.setLatLng([20.5, -0.09]);

Event(s):

onClick

marker.on("click", function(e) {
	var marker = e.target;
	//Do my work here
}.bind(this));

MouseOver

marker.on("mouseover", function(e) {
	var marker = e.target;
	//Do my work here
}.bind(this));

MouseOut

marker.on("mouseout", function(e) {
	var marker = e.target;
	//Do my work here
}.bind(this));

Popup:

BindPopup

marker.bindPopup(L.popup(),{
	offset: L.point(0,-10) //You can add an offset if you want to
});

OpenPopup

Let’s say you want to open the popup during a mouseover event.

marker.on("mouseover", function(e) {
	var marker = e.target;

	//Set the content to display in the popup
	marker.setPopupContent("My Text");
	//Now open the popup
	marker.openPopup();
}.bind(this));

ClosePopup

Let’s say you want to open the popup during a mouseout event.

marker.on("mouseout", function(e) {
	var marker = e.target;
	//Close the popup now
	marker.closePopup();
}.bind(this));

React: Leaflet Control

This entry is part 7 of 9 in the series React: Leaflet

In this tutorial I will demonstrate how to add a control to the map. Refer to the documentation for more information.

Before We Begin:

LayerControl

You can now do anything you want to do here.

var MyControl = L.Control.extend({
    onAdd: function (map){
        //Reference to the map
        this._map = map;

        //This is the container to return so it is available on the map
        var container = L.DomUtil.create("div");
        return container;
    },
    onRemove: function(){
        //Removes the control
        L.Control.prototype.onRemove.call(this);
        this._map = null;
    }
});

Add Control to Map

The options you add in the class definition are the options that the control gets.

var myControl = new MyControl({ position: "bottomright"});
myControl.addTo(this.map);

React: Leaflet LayerGroup

This entry is part 6 of 9 in the series React: Leaflet

In this tutorial I will demonstrate how to add a layer group control. Refer to the documentation for more information.

Before We Begin:

LayerGroup

You can now do anything you want to do here.

var MyLayerGroup = L.LayerGroup.extend({
    onAdd: function(map) {
        //Reference to the map
        this._map = map;
    },
    onRemove: function(){
        //Removes the layer
        L.LayerGroup.prototype.onRemove.call(this, map);
    },
    initialize: function (options) {
        L.LayerGroup.prototype.initialize.call(this);
        //The options sent in from initialisation
        L.Util.setOptions(this, options);
    }
});

Add LayerGroup to Map

var myLayerGroup = new MyLayerGroup();
myLayerGroup.addTo(this.map);

Overlay

If you want to add the layergroup to overlays menu.

this.layerControl.addOverlay(myLayerGroup, "My Layer Group");

React: Leaflet DomEvent

This entry is part 5 of 9 in the series React: Leaflet

In this tutorial I will demonstrate how to add events to your html control. Refer to the documentation for more information.

Before We Begin:

OnClick

L.DomEvent.on(htmlControl, "click", (e) => {
 	//Do your work here
});

 

 

 

React: Leaflet html Controls

This entry is part 4 of 9 in the series React: Leaflet

In this tutorial I will demonstrate how to add html controls to your leaflet map. Refer to the documentation for more information.

Before We Begin:

Really you can create any html control just substitute div for whatever you want. Below are just some basic examples.

Div

var divContainer = L.DomUtil.create("div", "myClassName");

Image

var img = L.DomUtil.create("img", "myClassName");

Label

var label = L.DomUtil.create("label", "myClassName");

Span

var span = L.DomUtil.create("span", "myClassName");

Input

var input = L.DomUtil.create("input", "myClassName");

BR

var br = L.DomUtil.create("br", "myClassName");

You can modify the html control with additional values such as

#style
divContainer.style.display = "";

#id
divContainer.id = "myId";

#name
divContainer.name = "myId";

#img src
divContainer.src = "";

#title
divContainer.title = "";

#innerHTML
divContainer.innerHTML = "";

#type
divContainer.type= "checkbox";

#checked
divContainer.checked= false;


Parent Control

You can add the control to a parent control in the following way.

var divContainer = L.DomUtil.create("div", "myClassName");

var subContainer = L.DomUtil.create("div", "myClassName", divContainer);

React: Leaflet EasyButton

This entry is part 3 of 9 in the series React: Leaflet

In this tutorial I will demonstrate how to add a easy button to your leaflet map. This will just be a basic example. For more information refer to the documentation.

Before We Begin:

Node Package Install:

npm install leaflet-easybutton --save

Edit app/home/leaflet/js/map.jsx:

//Add the leaflet easybutton package
require("leaflet-easybutton");
require("leaflet-easybutton/src/easy-button.css");

//Somehwere on your page add the following.


//Check out https://github.com/CliffCloud/Leaflet.EasyButton for more uses
L.easyButton("<div id="tag" class="glyphicon glyphicon-tag" />", function(btn, map) {
 	map.setView([42.3748204,-71.1161913],16);
}, { position: "topleft"}).addTo(this.map);

React: Leaflet Modal

This entry is part 2 of 9 in the series React: Leaflet

In this tutorial I will demonstrate how to add a modal dialog to your leaflet map. Refer to the documentation for more information.

Before We Begin:

Node Package Install:

npm install leaflet-modal --save

Edit app/home/leaflet/js/map.jsx:

//Add the leaflet modal package
require("leaflet-modal");
require("leaflet-modal/dist/leaflet.modal.min.css");

//Somewhere on your page add the following. You can even put it on a onclick event or whatever

//Create a test control for your modal control.
this.modalContainer = L.DomUtil.create("div");
map.openModal({
	zIndex: 10000, 
	element: this.modalContainer, //The container to display in the modal 
	OVERLAY_CLS: "overlay", //This is a built in class which you can change if you want
	MODAL_CLS: "modal", //This is a built in class which you can change if you want
	height: 200, width: 200, 
	MODAL_CONTENT_CLS: "modal-content",  //This is a built in class which you can change if you want
	CLOSE_CLS: "modal-close-hide" //The property for close class
});

Edit app/home/leaflet/css/map.css:

.modal-close-hide {
	/*Class for hiding the modal*/
	display: none;
}

React: Basic Leaflet Map Example

This entry is part 1 of 9 in the series React: Leaflet

In this tutorial I will walk you through incorporating leaflet map in your application. This is just a basic setup walkthrough. We do not deal with overlays or extending controls.

Documentation:

Leaflet
Leaflet Providers

Before We Begin:

If you have not done so already refer to how to Build a React/Python Site to get your basic site up and running.

Node Package Installs:

npm install leaflet-providers --save
npm install leaflet --save

Create Needed Folders/Files:

  • app
    • folder: leaflet
      • folder: css
        • file: map.css
      • folder: js
        • file: map.jsx

Webpack:

Add the following loader for handling images to your webpack.config.js file.

{ test: /.*\.(gif|png|jpe?g|svg)$/i, loader: "file-loader?hash=sha512&digest=hex&name=[name].[ext]" }

Edit app/leaflet/js/map.jsx:

We are going to create the map control. Refer to comments below for explanations.

window.jQuery = window.$ = require("jquery");
//React packages
var React = require("react");
var createReactClass = require("create-react-class");

//Leaflet packages
import L from "leaflet";
import "leaflet/dist/leaflet.css";

//LeafLet providers
require("leaflet-providers");

//map css you will create
import "../css/map.css";

var LeafLetMap = createReactClass({
    getInitialState: function() {
        return {};
    },
    displayMap: function() {
        //Setup/initialize the map control
        window.map = this.map = L.map("map", {
            attributionControl: false, //http://leafletjs.com/reference-1.2.0.html#control-attribution
        }).setView([0,0], 1);
        
        //A simple scale control that shows the scale of the current center of screen in metric (m/km) and imperial (mi/ft) 
        L.control.scale({ //http://leafletjs.com/reference-1.2.0.html#control-scale
            metric: false,
            imperial: true
        }).addTo(this.map);
        
        //You can check out all the free providers here https://github.com/leaflet-extras/leaflet-providers
        //Below are just examples
        this.layers = {
                OpenMapSurferRoads: L.tileLayer.provider('OpenMapSurfer.Roads'),
                HyddaFull: L.tileLayer.provider('Hydda.Full'),
                StamenTerrain: L.tileLayer.provider('Stamen.Terrain'),
                EsriWorldStreetMap: L.tileLayer.provider('Esri.WorldStreetMap'),
                EsriWorldTopoMap: L.tileLayer.provider('Esri.WorldTopoMap'),
                EsriWorldTerrain: L.tileLayer.provider('Esri.WorldTerrain'),
                OpenTopoMap: L.tileLayer.provider('OpenTopoMap'),
                OpenStreetMapBlackAndWhite: L.tileLayer.provider('OpenStreetMap.BlackAndWhite'),
                OpenStreetMapHOT: L.tileLayer.provider('OpenStreetMap.HOT')
            };

        //Add the default layer you want to use
        this.layers.OpenMapSurferRoads.addTo(this.map);

        //Add the layer control to the top left corner
        this.layerControl = L.control.layers(this.layers, {}, { position: "topleft" }).addTo(map);
    },
    componentDidMount: function() {
        //Done after mounting so that it sees the div you are going to map to
        this.displayMap();
    },
    render: function() {
        return (
            <div className="div-flex">
                <div id="map" key="map" className="map"></div>
            </div>
        );
    }
});

module.exports = { LeafLetMap:LeafLetMap };

Edit app/leaflet/css/map.css:

.map {
	/*Changes the width and height of the map*/
	height: 400px;
	width: 800px;
}

div.leaflet-top {
	/*OPTIONAL: This is only needed if your controls start going behind the map.*/
	z-index: 1001;
}

.leaflet-control-layers-toggle {
	/*Changes the width and height of the layer control*/
	height: 30px !important;
	width: 30px !important;
}

Edit app/home/js/home.jsx:

//Import your leaflet map control from the page you created above
import { LeafLetMap } from "../../leaflet/js/map.jsx";

//In the render function add your control
render: function() {
		return (
			<div className="div-flex">
		        	<LeafLetMap ref="map" />
			</div>
		);
	}

 

 

 

Javascript: Map

You can use the map function to return different results from an array to return a new array with new data.

For example if you want to build an array of controls you could do the following.

var newControls = myDataArray.map(function(rec, index){
    	        return <div></div>;
    	    });

 

JavaScript: Download Object Data

Sometimes you just want to send an object to be downloaded in which you don’t have any special requirements just download the data. To do so is really straight forward. Create the blob with the type then create the blobs object url.

var blob = new Blob([JSON.stringify(myDataObject)], {type: "application/force-download"});
url  = URL.createObjectURL(blob);

<a target="_blank" href={url} download="file.extension" />

Javascript: Math Functions

In this post I will show you how to perform math operations such as min, max, etc.

Min:

//Array
var maxValue = Math.min.apply(Math, myArray);

//Object Array
Math.min.apply(Math,myObjectArray.map(function(v){return v,key;}));

Max:

//Array
var maxValue = Math.max.apply(Math, myArray);

//Object Array
Math.max.apply(Math,myObjectArray.map(function(v){return v,key;}));

Sum:

var sumValue = myArray.reduce(function(a, b) { return a + b; }, 0);

Average:

var avgValue = sumValue / myArray.length;

Standard Deviation:

var stdevValue = Math.sqrt(sumValue);

JavaScript: Node & Lodash

In this tutorial we will be giving out some quick examples of Lodash functionality. To know more go here. There are so many examples and ways of doing Lodash. Check out the documentation.

Q: What is Lodash you ask?
A: It is a toolkit of Javascript functions that provides clean, performant methods for manipulating objects and collections. It is a “fork” of the Underscore library and provides additional functionality as well as some serious performance improvements.

First thing we need to do is install it. You will need a node site already ready to go. If you don’t have one you can follow this tutorial on setting a basic one up.

npm install lodash --save

On whatever page you are working with all you need to do is add the following to where your requires are.

var _ = require('lodash');

Now we can use the functionality as we wish. I will do some basic uses below.

Array difference:

If we want to find the difference of an array to the second array. The result would be “1” because 1 is not in the second array. Notice how it does not compare the second array to the first. It’s only checking which values 2 or 1 don’t exist in the second array.

_.difference([2, 1], [2, 3])
Array uniqWith:

If you want to get the unique items in an array you could use the following. It would return “2 45 3 7 8 1” only notice that the additional 45 is not displayed. It has been removed.

_.uniqWith([2, 45, 3, 7, 8, 45, 1], __.isEqual)

JavaScript: Node & UnderscoreJs

In this tutorial we will be giving out some quick examples of underscore.js functionality. To know more go here. There are so many to choose such as arrays, collections, objects, etc.

Q: What is underscore.js you ask?
A: It is a JavaScript library which provides utility functions for common programming tasks.

First thing we need to do is install it. You will need a node site already ready to go. If you don’t have one you can follow this tutorial on setting a basic one up.

npm install underscore --save

On whatever page you are working with all you need to do is add the following to where your requires are.

var _ = require('underscore');

Now we can use the functionality as we wish. I will do some basic uses below.

Array first:

Let’s say we want to get the first item in an array. This would return “456”.

_.first([456,6,32,11,99])
Array uniq:

If you want to trim out the duplicates in an array. This would return “456 6 32 11 99 89 45”.

_.uniq([456, 6, 32, 11, 99, 6, 89, 99, 45])
Collections contains:

If you want to check that a collection has a value. This will return “false” because 3 is not in the collection.

_.contains([4,5,6], 3)

 

 

 

 

 

 

Distinct Records in Object Array

Sometimes you need to determine the distinct objects in an array or distinct values in array. There are so many ways to do this. One way which I have used at times can be a bit slow depending on the size of your array.
From my investigation there is a lodash version that is much better. Once I do some testing I will update this but for now here is an example.
I expanded on the idea from Stack Exchange.

 var distinct = function(objectArray, param){
      var distinctResult = [];

      $.each(objectArray, function(i, currentObject){
            if (param !== null) {
                  if (distinctResult.filter(function(v) { return v[param] == currentObject[param]; }).length == 0)
                  {
                        distinctResult.push(currentObject);
                  }
            } else {
                  if(!exists(distinctResult, currentObject))
            {
                  distinctResult.push(currentObject);
            }
            }
      });

      return distinctResult;
};

var exists = function(arr, object){
    var compareToJson = JSON.stringify(object);
    var result = false;
    $.each(arr, function(i, existingObject){
        if(JSON.stringify(existingObject) === compareToJson) {
            result = true;
            return false; // break
        }
    });

    return result;
};

Java: Embed JavaScript

Let’s say you want to embed straight JavaScript code in your application.

pom.xml:

 <dependency>
      <groupId>org.mozilla</groupId>
      <artifactId>rhino</artifactId>
      <version>1.7.7.1</version>
</dependency>

*.Java

 import org.mozilla.javascript.*;

private static org.mozilla.javascript.Context cx = org.mozilla.javascript.Context.enter();

private static ScriptableObject scope = cx.initStandardObjects();

private static Function fct;

//You put the key to register in JavaScript and pass the variable in
scope.put(KEY, scope, VARIABLE);

cx.evaluateString(scope, JAVASCRIPTCODE, "script", 1, null);

fct = (Function)scope.get(METHOD_IN_CODE, scope);

Scriptable mapper = cx.newObject(scope);

//If you wanted to use this in the mapper as an example you would pass the key, value and context to the JavaScript function. That way when you write to the context in JavaScript it writes it to the applications context.
fct.call(cx, scope, mapper, new Object[] {key, value.toString(), context});