Change Style of GeoJSON circle marker by feature property value - colors

I have a GeoJSON feature collection of points assigned to lat/long coordinates, and i want to be able to assign them variable colors based on the value of a specific feature property.
I have seen examples creating creating chloropleths for different layers, but have not seen an example for imported points.
Using the layout, this is my getcolor function for values within a certain range of a specific feature property
$.getJSON("LRV_NoUTEP.geojson", function (data) {
// add GeoJSON layer to the map once the file is loaded
function getColor(d) {
return d < 0 ? "#a6cee3" : d < -50 ? "#1F62FF" : "#001C5C";
}
This is my geoJSON layer creating the points, and also creating a popup with all of the information, which works fine on its own.
L.geoJson(data, {
pointToLayer: function (feature, latlng) {
return new L.CircleMarker(latlng, {
radius: 10,
fillOpacity: 0.85,
color: getColor(feature.properties.anomalymgals),
});
//var marker = L.circleMarker(latlng, geojsonMarkerOptions);
},
onEachFeature: function (feature, marker) {
marker.bindPopup(
"<b> Latitude: </b>" + feature.properties.lat + "<br/>" +
"<b> Longitude: </b>" + feature.properties.long + "<br/>" +
"<b> Easting: </b>" + feature.properties.easting + "<br/>" +
"<b> Northing: </b>" + feature.properties.northing + "<br/>" +
"<b> Elevation_meters: </b>" + feature.properties.elev + "<br/>" +
"<b> Anomoly_mgals: </b>" + feature.properties.anomalymgals
);
},
}).addTo(mymap);
});
edited
<title>Leaflet </title>
<link type = "text/css" rel="stylesheet"
href="https://unpkg.com/leaflet#1.6.0/dist/leaflet.css"/>
<link rel="stylesheet" href = "comcat.css"/>
<link rel="stylesheet" href="https://fonts.googleapis.com/iconfamily=Material+Icons|Merriweather:400,400italic,700|Source+Sans+Pro:400,300,700"/>
<script src="https://unpkg.com/leaflet#1.6.0/dist/leaflet-src.js">
</head>
<body>
<div id="map" style="width: 600px; height: 400px;"></div>
<script>
//load the image
var mymap = new L.map('map', {
layers: [
L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
maxZoom: 19,
attribution: '',
id: '',
})
],
}).setView([44, -114.5], 9);
I can't seem to get the circle marker to return with new values, or anything at all when i introduce the getcolor function. What am I doing wrong? or is there a problem with formatting the way the function is is called on.

I found out what my problem is, when plugging all of my information into plunker, I am able to do it successfully. I am fairly new to using plunker, but it seems when i attempt to input the information into an existing html document, it seems to have a problem. I guess this turns into a general issue, where you are able to create a webpage, with a section just for a map followed by text. How should i go about doing this?

Related

KnockoutJS: components binding, working with objects as data type

I'm new to Knockout JS and I find this library very powerful, but quite hard to understand sometimes. The documentation is hudge, but it's always (too) small code snippets, so it's difficult to have the big picture, unless your coding style & philosophy paradigm are the same as KO developers.
I come from angular world, and I'm used to have an array where each item is an object with properties (id, name, etc). When I click a button, I "send" this object to a new component that will render it in a form.
I'm sure I'm missing something obvious, but I don't understand how to make things work, even with plugins like ko.mapping and ko.postbox.
Does anyone can help me to find the solution? In the working code above, I've posted my 3 very specific questions in the javascript area.
EDIT: I answered to them, but I don't know if it's a best practice or not.
var
// User class to give to each property the observable capacity
User = function (rawData) {
var self = this,
data = rawData || {};
self.id = ko.observable(data.id);
self.name = ko.observable(data.name);
},
// List component. initially in a separate file
// (small modifs so all can be in the same file for this demo)
cmplist = {
viewModel: function () {
var self = this;
self.users = ko.observableArray([
new User({id: 1, name: 'John'}),
new User({id: 2, name: 'Jack'}),
new User({id: 3, name: 'Smith'})
]);
// #ANSWER 1: initialize postbox event
self.user = ko.observable(new User()).publishOn('userEdit');
self.showEdit = function (user) {
// #QUESTION 1: how do I send this object to the
// users-form component. ko.postbox?
// #ANSWER 1: change the observable
self.user(user);
console.log('show', user);
};
},
template: ''
+ '<ul data-bind="foreach: users">'
+ '<li>'
+ '<button data-bind="click: $parent.showEdit">Edit</button>'
+ ' <span data-bind="text: name"></span>'
+ '</li>'
+ '</ul>'
},
// Form component, initially in a separate file
// (small modifs so all can be in the same file for this demo)
cmpform = {
viewModel: function () {
var self = this;
// #QUESTION 2: how do I recept the object sent by the
// list?
// #ANSWER 2: make the observable subscribe to event
self.user = ko.observable(new User()).subscribeTo('userEdit');
self.save = function () {
// #QUESTION 3: how do I notify the users-list cmp
// that object has changed? ko.postbox?
window.alert('save ' + ko.toJSON(self.user()));
console.log('save');
};
},
// #ANSWER 2: call user() with parenthesis to access properties
template: ''
+ '<form>'
+ '<p>Edit user <span data-bind="text: user().name"></span> '
+ 'with id <span data-bind="text: user().id"></span></p>'
+ '<input data-bind="textInput: user().name" />'
+ '<button data-bind="click: save">Save</button>'
+ '</form>'
};
// KO bootstrap, initially in a 3rd file
// (small modifs so all can be in the same file for this demo)
ko.components.register('users-list', cmplist);
ko.components.register('users-form', cmpform);
ko.applyBindings({});
ul {
border: 1px solid blue;
list-style: none;
float: left;
}
li {
border: 1px solid green;
}
form {
border: 1px solid red;
float: right;
margin-top: 20px;
}
ul, li, form {
padding: 5px;
}
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout-postbox/0.5.2/knockout-postbox.min.js"></script>
</head>
<body>
<users-list></users-list>
<users-form></users-form>
</body>
</html>

D3 Line graph is not rendering on IE8

We are using D3 library for creating line graph in a project. It is working as expected in modern browsers inlcuding mobile devices.
We are using Aight Library (https://github.com/shawnbot/aight) for IE8 compatibility but it is still not rendering the graph.
Any help or suggestion would be appreciated.
index.html :---
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script src="jquery.min.js"></script>
<script src="aight.js"></script>
<!-- <script>aight.browser.ie8 = true;</script> -->
<script src="d3.v2.js"></script>
<script src="d3nvtooltip.js"></script>
<script src="d3legend.js"></script>
<script src="d3line.js"></script>
<script src="d3linewithlegend.js"></script>
<script src="graph.js"></script>
<script src="aight.d3.js"></script>
<link href="d3.css" rel="stylesheet" type="text/css">
<style>
#test1 {
margin: 0;
padding: 0;
overflow: none;
}
</style>
</head>
<body>
<div id="test1">
<svg></svg>
</div>
</body>
</html>
graph.js : ---
$(document).ready(function() {
var margin = {top: 30, right: 10, bottom: 50, left: 60},
chart = d3LineWithLegend()
.xAxis.label('xAxis')
.width(width(margin))
.height(height(margin))
.yAxis.label('yAxis');
var svg = d3.select('#test1 svg')
.datum(generateData())
svg.transition().duration(500)
.attr('width', width(margin))
.attr('height', height(margin))
.call(chart);
chart.dispatch.on('showTooltip', function(e) {
var offset = $('#test1').offset(), // { left: 0, top: 0 }
left = e.pos[0] + offset.left,
top = e.pos[1] + offset.top,
formatter = d3.format(".04f");
var content = '<h3>' + e.series.label + '</h3>' +
'<p>' +
'<span class="value">[' + e.point[0] + ', ' + formatter(e.point[1]) + ']</span>' +
'</p>';
nvtooltip.show([left, top], content);
});
chart.dispatch.on('hideTooltip', function(e) {
nvtooltip.cleanup();
});
$(window).resize(function() {
var margin = chart.margin();
chart
.width(width(margin))
.height(height(margin));
d3.select('#test1 svg')
.attr('width', width(margin))
.attr('height', height(margin))
.call(chart);
});
function width(margin) {
var w = 800 - 20;
return ( (w - margin.left - margin.right - 20) < 0 ) ? margin.left + margin.right + 2 : w;
}
function height(margin) {
var h = 500 - 20;
return ( h - margin.top - margin.bottom - 20 < 0 ) ? margin.top + margin.bottom + 2 : h;
}
//data
function generateData() {
var data1 = [[1,250000],[2,249318],[3,248634],[4,247948],[5,247260],[6,246569],[7,245876],[8,245181],[9,244483],[10,243783],[11,243081],[12,242376],[13,241669],[14,240960],[15,240248],[16,239534],[17,238817],[18,238098],[19,237377],[20,236653],[21,235927],[22,235199],[23,234468],[24,233734],[25,232998],[26,232260],[27,231519],[28,230776],[29,230031],[30,229282],[31,228532],[32,227778],[33,227023],[34,226265],[35,225504],[36,224741],[37,223975],[38,223206],[39,222435],[40,221662],[41,220886],[42,220107],[43,219326],[44,218542],[45,217756],[46,216967],[47,216175],[48,215380],[49,214583],[50,213784],[51,212981],[52,212176],[53,211369],[54,210558],[55,209745],[56,208929],[57,208111],[58,207290],[59,206466],[60,205639],[61,204809],[62,203977],[63,203142],[64,202304],[65,201464],[66,200620],[67,199774],[68,198925],[69,198073],[70,197219],[71,196361],[72,195501],[73,194637],[74,193771],[75,192902],[76,192030],[77,191155],[78,190278],[79,189397],[80,188513],[81,187627],[82,186737],[83,185845],[84,184949],[85,184051],[86,183149],[87,182245],[88,181337],[89,180427],[90,179513],[91,178597],[92,177677],[93,176754],[94,175829],[95,174900],[96,173968],[97,173033],[98,172095],[99,171153],[100,170209],[101,169261],[102,168310],[103,167357],[104,166399],[105,165439],[106,164476],[107,163509],[108,162539],[109,161566],[110,160590],[111,159610],[112,158627],[113,157641],[114,156651],[115,155659],[116,154662],[117,153663],[118,152660],[119,151654],[120,150645],[121,149632],[122,148616],[123,147596],[124,146573],[125,145547],[126,144517],[127,143484],[128,142447],[129,141407],[130,140363],[131,139316],[132,138266],[133,137212],[134,136154],[135,135093],[136,134028],[137,132960],[138,131889],[139,130813],[140,129734],[141,128652],[142,127566],[143,126476],[144,125383],[145,124286],[146,123185],[147,122081],[148,120973],[149,119861],[150,118745],[151,117626],[152,116503],[153,115377],[154,114246],[155,113112],[156,111974],[157,110833],[158,109687],[159,108538],[160,107385],[161,106228],[162,105067],[163,103902],[164,102734],[165,101561],[166,100385],[167,99204],[168,98020],[169,96832],[170,95640],[171,94443],[172,93243],[173,92039],[174,90831],[175,89619],[176,88403],[177,87182],[178,85958],[179,84730],[180,83497],[181,82260],[182,81020],[183,79775],[184,78526],[185,77273],[186,76015],[187,74754],[188,73488],[189,72218],[190,70944],[191,69665],[192,68382],[193,67095],[194,65804],[195,64509],[196,63209],[197,61904],[198,60596],[199,59283],[200,57965],[201,56644],[202,55318],[203,53987],[204,52652],[205,51313],[206,49969],[207,48620],[208,47267],[209,45910],[210,44548],[211,43182],[212,41811],[213,40435],[214,39055],[215,37670],[216,36281],[217,34887],[218,33488],[219,32085],[220,30677],[221,29264],[222,27847],[223,26424],[224,24998],[225,23566],[226,22130],[227,20688],[228,19242],[229,17792],[230,16336],[231,14875],[232,13410],[233,11940],[234,10465],[235,8985],[236,7500],[237,6010],[238,4515],[239,3015],[240,1510],[241,0]];
return [
{
data: data1,
label: "Label"
}
];
}
});
From the documentation of Aight:
Aight is a collection of shims and polyfills that get IE8 up to speed
with a bare minimum of HTML5 compatibility, providing all of the
interfaces necessary to do HTML-only DOM manipulation with d3.js (and
other libraries that rely on those interfaces)
Your graph is svg-based, so you're going to have to find another solution if you need it to render in IE8 and lower. One such possibility would be to shim the svg functionality with R2D3 (raphael.js for D3). That will be able to handle some cases by translating to VML (via raphaƫl).

Get Latitude and Longitude values of placemark - Google Earth

I am using Google Earth API and I am new to it. I have marked a placemark using kml and added a click event to this. I want to get latitude and longitude values of this placemark. Though I am using getLatitude() and getLongitude() function, but values are not accurate. I want exactly the same values as defined in kml. The values I get differ by points.
Is there any way to to this?
Thanks
Shubhra
I have the following sample for you. It fetches a kml file and attaches a click event to the placemark. Alerted latitude and longitude values are exactly the same as kml file. Hope it helps.
<html>
<head>
<title>sample.html</title>
<script src="http://www.google.com/jsapi?key=ABQIAAAAwbkbZLyhsmTCWXbTcjbgbRSzHs7K5SvaUdm8ua-Xxy_-2dYwMxQMhnagaawTo7L1FE1-amhuQxIlXw"></script>
<script type="text/javascript">
var ge;
google.load('earth', '1');
function init() {
google.earth.createInstance('map3d', initCB, failureCB);
}
function initCB(instance) {
ge = instance;
ge.getWindow().setVisibility(true);
var href = 'http://code.google.com/'
+ 'apis/earth/documentation/samples/kml_example.kml';
google.earth.fetchKml(ge, href, function(kmlObject) {
if (kmlObject)
{
ge.getFeatures().appendChild(kmlObject);
google.earth.addEventListener(kmlObject, 'click', function(event) {
var placemark = event.getTarget();
alert('Latitude :' + placemark.getGeometry().getLatitude()
+' Longitude :' + placemark.getGeometry().getLongitude());
});
}
if (kmlObject.getAbstractView() !== null)
ge.getView().setAbstractView(kmlObject.getAbstractView());
});
}
function failureCB(errorCode) {
}
google.setOnLoadCallback(init);
</script>
</head>
<body>
<div id="map3d" style="border: 1px solid silver; height: 400px; width: 600px;"> </div>
</body>
</html>

How to create a "carousel"-like widget in spotify apps API?

Is it possible using the spotify apps API to create one of these widgets filled with my data of choice?
Yes, by using import/scripts/pager. Here's an example, extracted and simplified from the "What's New" app. Your pager.js:
"use strict";
sp = getSpotifyApi(1);
var p = sp.require('sp://import/scripts/pager');
var dom = sp.require('sp://import/scripts/dom');
exports.init = init;
function init() {
var pagerSection = dom.queryOne('#pager');
var datasource = new DataSource([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
var options = {
perPage: 5,
hidePartials: true,
orientation: 'vertical', // 'vertical', 'horizontal'
pagingLocation: 'top', // 'top', 'bottom'
bullets: false,
listType: 'list', // 'table', 'list'
context: 'aToplist' // some string unique for each pager
};
var pager = new p.Pager(datasource, options);
pager.h2.innerHTML = "Example Pager";
dom.adopt(pagerSection, pager.node);
}
function DataSource(data) {
var data = data;
this.count = function() {
return data.length;
};
this.makeNode = function(index) {
var dataItem = data[index];
var li = new dom.Element('li');
var nameColumn = new dom.Element('div', {
className: 'nameColumn',
html: '<div class="nameColumn">'+
'Name' + dataItem + ''+
'Creator' + dataItem +''+
'</div>'
});
dom.adopt(li, nameColumn);
return li;
};
}
Your index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="pager.css">
</head>
<body onload="sp = getSpotifyApi(1); sp.require('pager').init();">
<div id="wrapper">
<section class="toplists" id="bottomToplists">
<section id="pager" class="playlists playlistsTable toplist"></section>
</section>
</div>
</body>
</html>
And lastly, copy the whatsnew.css into your project and rename it to pager.css. You will of course need to clean up the css and modify the elements in your index.html to fit with your app but this is a good starting point.
The "What's New" app also has an example of a horizontal pager with album artwork. Take a look at this question and answer to figure out how to extract the source of the app.
Also note that I am not sure whether the pager.js will be part of the public API. If not then you can of course extract it into your own pager widget and use it anyway.

How to use Yahoo color picker to change background color

Hey all, I have this assignment where I need to integrate the Yahoo UI color picker into a website. When someone picks a color the background of the page need to become that color.
I followed instructions here http://developer.yahoo.com/yui/colorpicker/#events but I can't seem to figure out how to change the backgroundcolor to the picked color. I can change the background when someone picks a color, however I don't know how to get the color that is picked as input/ (see code for // comment) up until now i have this:
in head:
<!-- Dependencies -->
<script src="http://yui.yahooapis.com/2.8.2r1/build/utilities/utilities.js" ></script>
<script src="http://yui.yahooapis.com/2.8.2r1/build/slider/slider-min.js" ></script>
<!-- Color Picker source files for CSS and JavaScript -->
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.8.2r1/build/colorpicker/assets/skins/sam/colorpicker.css">
<script src="http://yui.yahooapis.com/2.8.2r1/build/colorpicker/colorpicker-min.js" ></script>
then in body tag: class="yui-skin-sam"
and in body:
<div id="container"></div>
<script type="text/javascript">
var picker = new YAHOO.widget.ColorPicker("container", {
showhsvcontrols: true,
showhexcontrols: true,
images: {
PICKER_THUMB: "picker_thumb.png",
HUE_THUMB: "hue_thumb.png"
}
});
//a listener for logging RGB color changes;
//this will only be visible if logger is enabled:
var onRgbChange = function(o) {
/*o is an object
{ newValue: (array of R, G, B values),
prevValue: (array of R, G, B values),
type: "rgbChange"
}
*/
// with this code i change the background when a color is picked, but not with the input col.
// document.body.style.backgroundColor = 'green';
YAHOO.log("The new color value is " + o.newValue, "info", "example");
}
//subscribe to the rgbChange event;
picker.on("rgbChange", onRgbChange);
</script>
The syntax for setting the background color to a RGB value (what o.newValue gives) looks like:
doc.style.backgroundColor="rgb(239,239,239)";
...so, try something like this:
document.body.style.backgroundColor = "rgb(" + o.newValue[0] + "," + o.newValue[1] + "," + o.newValue[2] + ");"

Resources