Simple Leaflet Map with Selection color.

Working Map

This is a simple Leaflet map using a static GeoJSON file (BaseBallFinal.json) I use JQuery's getJSON function to read the file. I start with the basic map view and basemap, here I use osm (OpenStreetMap), define what the layer is going to look like, I chose circleMarker, and define the popup format and data. Last I read the GeoJSON file and add the data to the layer. This map is similar to my second map but now I have extra code to define colors for the selected record.

map1

Now the code.

In the head section, I have the list of libraries I used, basically Leaflet, JQuery, and JQuery UI (User Interface), both the JavaScript and CSS files.

<!DOCTYPE html>
<html>
<head>
	<title>GeoJSON tutorial - Leaflet</title>

	<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" />
	<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>


Now the CSS information. This only a map but here you define the height and width in pixals.
<style>
		#map {
			width: 800px;
			height: 600px;
		}
</style>
Define the div for the map.

Now the data, here I define the GeoJSON file. It's a static file instead of a web service (REST) feed. Since this data won't change this method saves on server processing.

</head>
<body>
<div id="map" > </div>
<script> var url = 'BaseBallFinal.json'; // my GeoJSON data source, in the same folder as my HTML file.
Now I need to define the base map.

The map is declared with the center and zoom level set for the US.

I'm using OpenStreetMap as the basemap, it's a very clean popular map.
  
	var map = L.map('map').setView([37.52715,-96.877441], 4); 

	var osm=new L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png',{ 
				attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'});
		
Since I'm using circleMarkers, I have to define how they look. Most of the symbology is defined when I'm defining the layer further in the code. The getColor function here reads the past value for League from the GeoJSON file and if it has the value 'NL' use blue as the color and 'AL' gets red. Anything else gets a white color making it easy to find the feature with a typo or missing data error.
	// Set function for color ramp
	function getColor(league){
		return league == 'NL' ? 'blue' :
			  league == 'AL' ? 'red' :
				'white';
	       }	
			


The forEachFeature function is similar to the second map. It has an on click event, that is an event fired off when you click on a feature, here it gets the features coordinates and passes them along to an onMapClick function.

No changes where made in defining the popup template with a hyperlink, bound to to each feature.
	function forEachFeature(feature, layer) {

        	layer.on('click', function (e) {
 
					// get coordinates from GeoJSON
					var coords = e.target.feature.geometry.coordinates
					//pass coords to function to create marker.(Yellow circle)
					onMapClick(coords);
			});

	
			var popupContent = "<p>The <b>" +
					feature.properties.Team + "</b> play here,</br> They are in the " +
					feature.properties.League + "</br>" +
					'<a href="'+ feature.properties.Website +'" target="_blank">Website</a></p>' ;
							
			if (feature.properties && feature.properties.popupContent) {
				popupContent += feature.properties.popupContent;
			}
				layer.bindPopup(popupContent);
	};

	

Now I'm ready to define the layer. I'm calling it bbTeam and the null means not data source yet, however it should use the forEachFeature function for the onEachFeature option.

The pointToLayer is a function that converts the data to points, and for every feature retun a circleMarker at that location using the options below. Notice I use a getColor function to define what color which depends on the value defined in the Laegue field of the GeoJSOn data.
		
		
  var bbTeam = L.geoJSON(null, {
			onEachFeature: forEachFeature, 
			pointToLayer: function (feature, latlng) {
				return L.circleMarker(latlng, {
					radius:6,
					opacity: .5,
					//color: "#000",
					color:getColor(feature.properties.League),
					fillColor:  getColor(feature.properties.League),
					fillOpacity: 0.8

				}).bindTooltip(feature.properties.Name);

			}
	  });


 
Next using the JQuery getJSON function, read the data at the url location, pass it to the function as data, and add it to the layer. Finally add the layer to the map.

  	// Get GeoJSON data and create features.
	$.getJSON(url, function(data) {
		bbTeam.addData(data);
	});
	
    bbTeam.addTo(map);
    
 
Here is the magic, the forEachFeature function had an on click event, it grabbed feature coordinates, and passed them along to this function. First we declare a global variable called clickmark this is basically the yellow circleMarker layer. Next we check if a prior yellow circleMarker is on our map (defined). So if it's not undefined, it must exist, so remove it.

We also take the passed coordinates (see console.log for them), flip the X,Y to Lat, Lng and create a yellow circleMarker at the clicked features coordinates, the trick is to maker it bigger, solid, and place it over the features circleMarker, hiding it.
// click marker
  var clickmark;

  // When you click on a circleMarker, it calls the onMapClick function and passes the layers coordinates.
  // I grab the coords which are X,Y, and I need to flip them to latLng for a marker,  
  function onMapClick(coords) {
		console.log(coords);
		var thecoords = coords.toString().split(',');
		var lat = thecoords[1];
		var lng = thecoords[0];
		
		if (clickmark != undefined) {  //if prior marker exists, remove it.
		  map.removeLayer(clickmark);
		};
  
		 clickmark = L.circleMarker([lat,lng],{
			radius: 8,
			color: "yellow",
			fillColor:  "yellow",
			fillOpacity: 1}
		 ).addTo(map);
	}
// end of code for click marker.


That is it, toss in some closing tags and I am done. My finished script,    My GeoJSON data
</script> 
</body>
</html>