Why is Leaflet Ajax not processing and displaying GeoJSON data? - json

I have been trying for weeks to get Leaflet Ajax to accept data requests from the Land Information New Zealand (LINZ) API without success.
I have a valid key (not included in the snippet) and have tried several tests to load this data in. Other datasets from the LINZ API do not worth either.
What am I doing wrong here?
<html>
<head>
<!-- Style -->
<link rel="stylesheet" href="css/style.css">
<!-- Leaflet -->
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
crossorigin=""/>
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js"
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
crossorigin=""></script>
<!-- Leaflet Ajax -->
<script type='text/javascript' src="./js/leaflet.ajax.js"></script>
<div id="map"></div>
</head>
<body>
<script>
map = L.map('map').setView([-41.29132, 174.77931],16)
var OpenTopoMap = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
maxZoom: 17,
attribution: 'Map data: © OpenStreetMap contributors, SRTM | Map style: © OpenTopoMap (CC-BY-SA)'
});
OpenTopoMap.addTo(map)
property_tiles_link = "https://data.linz.govt.nz/services/query/v1/vector.json?key=KEY_GOES_HERE&layer=50804&x=172.61706383056807&y=-43.57379489129212&max_results=3&radius=10000&geometry=true&with_field_names=true"
geojson = new L.GeoJSON.AJAX(property_tiles_link).addTo(map)
console.log(geojson)
overlays = {
"geojson": geojson
}
basemaps = {
"OpenTopoMap": OpenTopoMap
}
L.control.layers(basemaps, overlays).addTo(map)
</script>
</body>
The code snippet results in this output:
Looking through the logged GeoJSON object does not seem to show any successfully parsed data. The error message in Firefox translates roughly to "The configuration of HTML characters hasn't been declared. The document will show 'rubbish' text in some configurations of the browser."
Any ideas would be super helpful!
An example of the response:
{
"vectorQuery": {
"layers": {
"50804": {
"crs": {
"type": "name",
"properties": {
"name": "EPSG:4326"
}
},
"field_names": ["id", "title_no", "status", "type", "land_district", "issue_date", "guarantee_status", "estate_description", "number_owners", "spatial_extents_shared"],
"type": "FeatureCollection",
"features": [{
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[175.4776337167, -41.2221699],
[175.4782420833, -41.2225527833],
[175.4801549333, -41.2237566167],
[175.476269, -41.2259343],
[175.47357595, -41.22444375],
[175.4776337167, -41.2221699]
]
]
]
},
"distance": 0,
"type": "Feature",
"properties": {
"id": 1468560,
"title_no": "WN53B/277",
"status": "LIVE",
"type": "Freehold",
"land_district": "Wellington",
"issue_date": "1998-04-16 00:00:00",
"guarantee_status": "Guarantee",
"estate_description": "Fee Simple, 1/1, Lot 1 Deposited Plan 85426, 110,945 m2",
"number_owners": 1,
"spatial_extents_shared": false
},
"id": 1191838
}, {
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[175.48005638330002, -41.2282570333],
[175.48105425000003, -41.2286012667],
[175.4789359, -41.2297867333],
[175.47874645, -41.2298923],
[175.4767530167, -41.2310074667],
[175.47604405, -41.2314040667],
[175.47550265, -41.23170695000001],
[175.4749415833, -41.2320208833],
[175.4745023167, -41.2322666333],
[175.474015, -41.2317699833],
[175.4735909, -41.23133785000001],
[175.4735833, -41.2313303667],
[175.4732046667, -41.23094425],
[175.4728425667, -41.2305752833],
[175.4725057833, -41.2302328833],
[175.4722412333, -41.2299625],
[175.4719444667, -41.2296600833],
[175.4715930333, -41.22930195],
[175.47127355, -41.2289763667],
[175.4712437333, -41.2289459833],
[175.4708617, -41.22855675],
[175.4704157833, -41.2281024167],
[175.4699766167, -41.227654983300006],
[175.4692410167, -41.2269055],
[175.4692395833, -41.2269040667],
[175.46921793330003, -41.2268834667],
[175.4718439333, -41.2254143333],
[175.4733724167, -41.2245578167],
[175.48005638330002, -41.2282570333]
]
]
]
},
"distance": 134,
"type": "Feature",
"properties": {
"id": 2348803,
"title_no": "WN103/58",
"status": "LIVE",
"type": "Freehold",
"land_district": "Wellington",
"issue_date": "1899-10-23 00:00:00",
"guarantee_status": "Guarantee",
"estate_description": "Fee Simple, 1/1, Lot 75 Deposited Plan 579, 409,390 m2",
"number_owners": 1,
"spatial_extents_shared": true
},
"id": 5113879
}, {
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[175.48005638330002, -41.2282570333],
[175.48105425000003, -41.2286012667],
[175.4789359, -41.2297867333],
[175.47874645, -41.2298923],
[175.4767530167, -41.2310074667],
[175.47604405, -41.2314040667],
[175.47550265, -41.23170695000001],
[175.4749415833, -41.2320208833],
[175.4745023167, -41.2322666333],
[175.474015, -41.2317699833],
[175.4735909, -41.23133785000001],
[175.4735833, -41.2313303667],
[175.4732046667, -41.23094425],
[175.4728425667, -41.2305752833],
[175.4725057833, -41.2302328833],
[175.4722412333, -41.2299625],
[175.4719444667, -41.2296600833],
[175.4715930333, -41.22930195],
[175.47127355, -41.2289763667],
[175.4712437333, -41.2289459833],
[175.4708617, -41.22855675],
[175.4704157833, -41.2281024167],
[175.4699766167, -41.227654983300006],
[175.4692410167, -41.2269055],
[175.4692395833, -41.2269040667],
[175.46921793330003, -41.2268834667],
[175.4718439333, -41.2254143333],
[175.4733724167, -41.2245578167],
[175.48005638330002, -41.2282570333]
]
]
]
},
"distance": 134,
"type": "Feature",
"properties": {
"id": 4177014,
"title_no": "94991",
"status": "LIVE",
"type": "Leasehold",
"land_district": "Wellington",
"issue_date": "2003-06-10 09:00:00",
"guarantee_status": "Guarantee",
"estate_description": "Leasehold, 1/1, Lot 75 Deposited Plan 579, 409,390 m2",
"number_owners": 1,
"spatial_extents_shared": true
},
"id": 5116291
}]
}
}
}
}

The Leaflet-ajax plugin expects directly a GeoJSON compliant object in the loaded data, whereas in the sample response you show, the structure of the response is:
{
"vectorQuery": {
"layers": {
[layerId]: {
// GeoJSON FeatureCollection
}
}
}
}
Therefore you have to convert this data into a GeoJSON object first. Here in this case it looks quite simple, as you just have to extract the FeatureCollection. You can use leaflet-ajax middleware option to perform this conversion between the reception of the data and before it is processed to be transformed into Leaflet layers:
new L.GeoJSON.AJAX("url", {
middleware(rawData) {
// Extract the GeoJSON FeatureCollection
const layerId = 50804;
return rawData.vectorQuery.layers[layerId];
}
});

Related

Getting multiple sets of markers on Mapbox from the same JSON file

I have a JSON file that I want to get 4 separate sets of markers from. I can get all of the markers to show up but I need to be able to call sets based on the TARGET_GROUP_NAME.
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"site_code": "S0001726",
"short_title": "Boddington Bauxite",
"stage": "Operating",
"lon": "116.455902",
"lat": "-32.931561",
"target_group_name": "BAUXITE - ALUMINA"
},
"geometry": {
"type": "Point",
"coordinates": [
116.455902,
-32.931561
]
}
},
The code I have currently is:
map.on('load', () => {
map.addSource('mines', {
type: 'geojson',
data: 'https://raw.githubusercontent.com/ParkaviMathi/Project_3/main/static/clean_mines.geojson',
});
map.addLayer({
'id': 'mines-layer',
'type': 'circle',
'source': 'mines',
'paint': {
'circle-radius': 4,
'circle-stroke-width': 2,
'circle-color': 'red',
'circle-stroke-color': 'white'
}
});
Any direction is greatly appreciated.

Convert JSON to nodes and links?

I'm trying to create a D3 Force-Directed Graph variant I found here https://github.com/vasturiano/3d-force-graph using JSON data on 30,000+ Steam Games.
I'd like to link games by their first 'steamspy_tags' which requires converting this data to nodes and links like so
{ "nodes": [
{"id": "Myriel", "group": 1},
{"id": "Napoleon", "group": 1}],
"links": [
{"source": "Napoleon", "target": "Myriel", "value": 1},
{"source": "Mlle.Baptistine", "target": "Myriel", "value": 8}
Is there an easy way to convert raw JSON to node and link data to format it for the graph?
The data is structured like so:
[
{
"appid": 10,
"name": "Counter-Strike",
"developer": "Valve",
"categories": "Multi-player;Online Multi-Player;Local Multi-Player;Valve Anti-Cheat enabled",
"genres": "Action",
"steamspy_tags": "Action;FPS;Multiplayer"
},
{
"appid": 20,
"name": "Team Fortress Classic",
"developer": "Valve",
"categories": "Multi-player;Online Multi-Player;Local Multi-Player;Valve Anti-Cheat enabled",
"genres": "Action",
"steamspy_tags": "Action;FPS;Multiplayer"
},
The graph code itself is as follows:
<head>
<style> body { margin: 0; } </style>
<script src="//unpkg.com/element-resize-detector/dist/element-resize-detector.min.js"></script>
<script src="//unpkg.com/3d-force-graph"></script>
<!-- <script src="../../dist/3d-force-graph.js"></script>-->
</head>
<body>
<div id="3d-graph"></div>
<script type="module">
import { UnrealBloomPass } from '//unpkg.com/three/examples/jsm/postprocessing/UnrealBloomPass.js';
const elem = document.getElementById('3d-graph');
const Graph = ForceGraph3D()(elem)
.jsonUrl('../datasets/developers/valve.json')
.nodeAutoColorBy('maintag')
.nodeVal('PosRat')
.backgroundColor('#171717')
.cooldownTicks(100)
.height(window.innerHeight - 60)
.nodeLabel(node => `${node.title}: ${node.release_date}: ${node.maintag}`)
.onNodeHover(node => elem.style.cursor = node ? 'pointer' : null)
.onNodeClick(node => window.open(`https://store.steampowered.com/app/${node.id}`, '_blank'));
const bloomPass = new UnrealBloomPass();
bloomPass.strength = 1.0;
bloomPass.radius = 0.3;
bloomPass.threshold = 0.25;
Graph.postProcessingComposer().addPass(bloomPass);
Graph.onEngineStop(() => Graph.zoomToFit(400));
</script>
</body>

Vue.js Filtered list Method

I am still learning Vue.js. At the moment I am trying to make a simple filtered list method that pulls the data from a json file in Vue. I think that I am having trouble figuring out the correct syntax.
I just cant seem to get it right. Any help is more than welcome :)
This is Vue file:
<template>
<section>
<ul>
<li v-for="product in rings" :key="product">
{{product.title}}
</li>
</ul>
</section>
</template>
<script>
import data from '#/assets/data.json';
export default {
data() {
return {
products: []
}
},
methods: {
computed: {
rings(){
return this.products.filter(product => product.type == 'Ring')
}
}
}
}
</script>
And this is the Json file:
{ "products": [
{
"title": "Ring 1",
"description": "something",
"type": "Ring",
"year": "2018",
"image": "...",
"price": "2000,00 kr."
},
{
"title": "Halskæde 1",
"description": "something",
"type": "Halskæde",
"year": "2018",
"image": "...",
"price": "2000,00 kr."
},
{
"title": "Armbånd 1",
"description": "something",
"type": "Armbånd",
"year": "2018",
"image": "...",
"price": "2000,00 kr."
},
{
"title": "Ørering 1",
"description": "something",
"type": "Ørering",
"year": "2018",
"image": "...",
"price": "2000,00 kr."
}
]
}
You imported the data but never used anywhere inside the component:
import data from '#/assets/data.json';
// notice the data here is just a variable and it has nothing to do with the
// component's data property
export default {
data () {
return {
products: data.products // init products with imported data
}
},
Or with the destructuring syntax:
import { products } from '#/assets/data.json';
export default {
data () {
return {
products // init products with imported data
}
},

How to properly pass Json data to fusioncharts? -Multisiries-

First time poster, thanks for the attention.
Using web api to generate object to be consumed by fusioncharts (Multiseries). Object is produced as array of 2 classes (ChartCategories and ChartSeries) output seems fine and is retrieved in angular controller as data. yet after building up $scope.categories and $scope.dataset using data, I am unable to generate the chart with error 'No data to display'.
Partial Html template for chart:
<div id = "Div1">
<fusioncharts
width="400"
height="200"
type="mscolumn2d"
chart="{{attrs}}"
categories="{{categories}}"
dataset="{{dataset}}"
></fusioncharts>
</div>
data retrieved from web api: (copied + pasted)
[
[
{
"category": [
{
"label": "7/18/2014 9:30:01 AM"
},
{
"label": "7/18/2014 9:40:00 AM"
},
{
"label": "7/18/2014 9:50:00 AM"
}
]
},
null,
null
],
[
null,
{
"seriesname": "Free_Memory",
"renderas": "Line",
"data": [
{
"value": "6632"
},
{
"value": "5136"
},
{
"value": "6376"
}
]
},
{
"seriesname": "Page_Life_Exp",
"renderas": "Line",
"data": [
{
"value": "48859"
},
{
"value": "49458"
},
{
"value": "50057"
}
]
}
]
]
and in angular, I set the $scope.categories and $scope.dataset like so: $scope.attr is hard coded for the time being.
$scope.categories = data[0][0];
$scope.dataset = data[1][1];
What is needed in order to generate the graph?
Refer to http://jsfiddle.net/ayanonly1/yh1cvjqw/
I think following changes will make the chart live.
$scope.categories = [data[0][0]];
$scope.dataset = data[1].slice(1);

How to use Kimono API

Goal: Parse JSON API data with jquery so I can display the information on my static (no backend) website in a styled list.
I have created an API using Kimono, and now need to display this information. Any help on just where to get started would be great.
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script>
function kimonoCallback(data) {
// do something with the data
}
$.ajax({
"url":"http://www.kimonolabs.com/api/42ts6px8?apikey=363e7e1d3fffb45d424ad535ebdc233d&callback=kimonoCallback",
"crossDomain":true,
"dataType":"jsonp"
});
</script>
Example JSON Data:
{
"name": "HN",
"count": 30,
"frequency": "daily",
"version": 1,
"newdata": true,
"lastrunstatus": "success",
"lastsuccess": "Wed Mar 19 2014 23:23:40 GMT+0000 (UTC)",
"nextrun": "Thu Mar 20 2014 23:23:40 GMT+0000 (UTC)",
"results": {
"collection1": [
{
"property1": {
"href": "http://blog.samaltman.com/new-rfs-breakthrough-technologies",
"text": "New RFS – Breakthrough Technologies"
},
"source": "(samaltman.com)"
},
{
"property1": {
"href": "https://www.unrealengine.com/blog/welcome-to-unreal-engine-4",
"text": "Welcome to Unreal Engine 4"
},
"source": "(unrealengine.com)"
},
{
"property1": {
"href": "https://www.crypto101.io/",
"text": "Crypto 101"
},
"source": "(crypto101.io)"
},
{
"property1": {
"href": "http://sivers.org/full",
"text": "What if you didn't need money or attention?"
},
"source": "(sivers.org)"
}
Thank you for any help.
You do not need parse the JSON, when you specify dataType:'jsonp' property in $.ajax(), jQuery will automatically parse the response from the server and pass the parsed JSON object to your success callback kimonoCallback(data), you need parse the JSON if you remove the dataType:"jsonp" from your $.ajax() call only (with JSON.parse(), jQuery.parseJSON()... etc).
<script>
function kimonoCallback(data) {
console.log(data);
$.each(data.results, function( index, collection ) {
$.each(collection, function( index, object ) {
console.log(object.source);
console.log(object.property1.text);
//console.log(object.anotherproperty);
//.....
});
});
}
$.ajax({
"url":"http://www.kimonolabs.com/api/42ts6px8?apikey=363e7e1d3fffb45d424ad535ebdc233d&callback=kimonoCallback",
"crossDomain":true,
"dataType":"jsonp"
});
</script>