How to increase performance when show geoJson using Mapkit.js? - javascript

I have a 40mb detailed geojson and using the following code to visualize it using the Apple Mapkit.js:
mapkit.importGeoJSON('/assets/map.json', {
itemForMultiPolygon: (collection: any, geoJSON: any) => {
const points = collection
.getFlattenedItemList()
.reduce(
(points: any, overlay: any) => points.concat(overlay.points),
[]
);
return new mapkit.PolygonOverlay(points);
},
// When all the data has been imported, we can show the results.
geoJSONDidComplete: function(overlays:any) {
// map.addItems(overlays);
map.showItems(overlays.getFlattenedItemList());
}
});
This is the same code as Apple Mapkit.js promote in their examples. It takes some time to render and works, but when I zoom or move over the map it works slowly and Chrome shows 1GB of RAM. Some errors about Canvas issues appear as well.
However, when I visualize the same geojson in Github with their Azure Maps it works fast and Chrome shows only 15-20mb.
How to increase the performance in this case?

Related

pdftron copy wrong text

I want to use pdftron and all things work perfect but when i copy text from pdf some characters convert to blank square and question mark, any idea?
here is my pdf.
As you can see below:
I wrote this code:
WebViewer({
path: '/assets/plugins/pdftron',
initialDoc: '/practical.pdf',
fullAPI: true,
disableLogs: true
}, document.getElementById('pdf')).then((instance) => {
// PDFNet is only available with full API enabled
const { PDFNet, docViewer } = instance;
let Feature = instance.Feature;
instance.disableFeatures([Feature.NotesPanel]);
docViewer.on('documentLoaded', () => {
// call methods relating to the loaded document
});
instance.textPopup.add({
type: 'actionButton',
img: '/language.svg',
onClick: () => {
const quads = docViewer.getSelectedTextQuads(docViewer.getCurrentPage());
const text = docViewer.getSelectedText();
$("#out-pdf").html(text);
console.log(quads);
},
});
});
Document does seem to cause incorrect extraction. Extraction is not defined by PDF specification so every viewer handles cases little differently. I your case there is a probably a malformed or incomplete font or unicode map included in the document. We've added multiple fixes to our core components and with those fixes extraction happens correctly. Unfortunately current release of WebViewer does not include these fixes yet. We cannot give exact time schedule when fixes will be land to the WebViewer, but should be at least part of our next major release. For now I would try to see if you can recreate the document and see if that helps. Most of the documents we see and test have no problem with extraction.
Could you create ticket through our support https://www.pdftron.com/form/request/ and attach the document that this happens to the ticket, so I can take a closer look on and get issue resolved faster.

DeviceOrientation Compass Android

I try to implement a compass using the deviceorientation event. I want to use the rotation to rotate an arrow facing in the viewing direction. I'm simply rotating the Image when the deviceorientation changes.
On iOS this works like charm by doing the following:
if (typeof DeviceOrientationEvent.requestPermission === "function") {
//#ts-ignore
DeviceOrientationEvent.requestPermission()
.then(permissionState => {
if (permissionState === "granted") {
this.compassActive = true;
window.addEventListener(
"deviceorientation",
eventData =>
this.zone.run(() => {
if(!this.compassActive){
return false;
}
//#ts-ignore
this.rotatePlayerIcon(eventData.webkitCompassHeading);
}),
false
);
}
})
.catch(console.error);
Since the DeviceOrientationEvent.webkitCompassHeading gives me a clockwise world based presentation of the rotation of the device.
I try the same on Android but I can't find a world based solution. webkitCompassHeading does not exist on android so I tried using just eventData.alpha. But this gives 0 based on the rotation it was when the event was fired, not based on world north.
All the Guides I find seem outdated.
How do I get a clockwise compass on android like I get on iOS?
bellow youll seea compass of vtm-mapsforge. it also includes an arrow. appart from the usual magnetometer-accelerometer sensors I recommend using location bearing as the sensors are not at all accurate and get easily disrupted.the nice thing about the compass is that it includes code to make it rotate smoothly as the raw output from the sensors is often noisy.
For the Java code look at this, it is the original version of the vtm-mapsforge compass
The problem is that alpha is not absolute, means 0 is not north instead 0 is where the device is pointing on activation.
The best way to fix for chrome-based browsers, like most standard Android Browsers ist using an AbsoluteOrientationSensor from W3C Generic Sensor API polyfills.
Github
The Project I used it in is Typescript based. So here is a Typescript example:
import {AbsoluteOrientationSensor} from 'motion-sensors-polyfill'
const options = { frequency: 60, referenceFrame: 'device' };
const sensor = new AbsoluteOrientationSensor(options);
sensor.addEventListener('reading', e => {
this.zone.run(() => {
var q = e.target.quaternion;
let alpha = Math.atan2(2*q[0]*q[1] + 2*q[2]*q[3], 1 - 2*q[1]*q[1] - 2*q[2]*q[2])*(180/Math.PI);
if(alpha < 0) alpha = 360+ alpha;
this.alpha = 360 - alpha;
this.rotatePlayerIcon(360 - alpha)
})
});
sensor.start();

Geojson map with D3 only rendering a single path in a feature collection

I'm trying to draw a geojson map of some regions of Colombia. Currently it only shows a single path:,
My feature collection has 52 features, but I can only draw this one feature. I do not know what I'm doing wrong, I'm based my code on other tutorials. How can I do to show all the paths?
var features = mapData.features;
console.log(features);
// Update color scale domain based on data
// Draw each province as a path
mapLayer.selectAll('path')
.data(features)
.enter().append('path')
.attr('d', path)
.attr('vector-effect', 'non-scaling-stroke')
Here is my full code:
https://plnkr.co/edit/kSDtyyoWr9TSEDZ5Letv?p=preview
Problem
All your features are drawing, you are correctly using your path and enter cycle. To see, set your fill to none:
You can see them when inspecting the svg: all the paths are there.
Why don't you see them in the map when they have fill? Because the the polygons are inverted, they cover the entire world except for the region of interest. While most other geographic libraries/renderers treat geojson as Cartesian, D3 does not. This means winding order matters. Your coordinates are wound in the wrong order.
Solution
To properly fill, draw all features, and support mouse interaction, you'll need to reverse the winding order of the polygons. You can do this on the fly, or create new geojson files to store the pre-reversed data.
To do so let's take a look at your data. You are working with only features that are MultiPolygons, let's look at the structure:
{
type:"Feature",
properties: {...},
geometry: {
type: "MultiPolygon",
coordinate: /* coordinates here */
}
}
Coordinates are structured as so:
coordinates:[polygons] // an array of polygons
The individual polygons are structured as so:
[outer ring][inner ring][inner ring]... // an array of coordinates for an outer ring, an array of coordinates for each hole (inner ring).
Polygon rings are structured as an array of long lats, with the first and last values being the same.
[x,y],[x,y]....
So, to reverse the ordering of the coordinates, we need to reverse the items in the ring arrays:
features.forEach(function(feature) {
if(feature.geometry.type == "MultiPolygon") {
feature.geometry.coordinates.forEach(function(polygon) {
polygon.forEach(function(ring) {
ring.reverse();
})
})
}
})
If we had polygons in the mix too (they are slightly less nested), we could use:
features.forEach(function(feature) {
if(feature.geometry.type == "MultiPolygon") {
feature.geometry.coordinates.forEach(function(polygon) {
polygon.forEach(function(ring) {
ring.reverse();
})
})
}
else if (feature.geometry.type == "Polygon") {
feature.geometry.coordinates.forEach(function(ring) {
ring.reverse();
})
}
})
Here's an updated plunker
It is drawing all the paths. See the DOM for the SVG in a web page inspector to confirm. However, you are seeing only the top one which happens to be the larger area because of fills. Try adding .style('fill', 'none') to the paths addition in JS. or the following in CSS
path {
fill: none
}
If someone will see a similar problem, I created a tool which will help you to rewind or reverse geojson
https://observablehq.com/#bumbeishvili/rewind-geojson
You can run it as a snippet just bellow
<div class="notebook-content">
</div>
<script type="module">
import notebook from "https://api.observablehq.com/#bumbeishvili/rewind-geojson.js"; // "download code" url
document.querySelector('.notebook-content').innerHTML =notebook.modules[0].variables
.filter(d=>d)
.map((d,i)=>` <div class=" observable-wrapper div-number-${i}"></div>`)
.join('')
.concat('<div style="display:none" class="hidden"></div>')
import {Inspector, Runtime} from "https://unpkg.com/#observablehq/runtime#3/dist/runtime.js";
let i=1;
Runtime.load(notebook, (variable) => {
if(i==4 ){i++; return new Inspector(document.querySelector(`.hidden`));}
if(i==13)return;
return new Inspector(document.querySelector(`.observable-wrapper:nth-child(${i++})`));
});
</script>

d3 + leaflet path fill issue

I'm working on a timelapsed filled map using Leaflet as a baselayer and a d3 topojson file so I can color in some countries. I used http://bost.ocks.org/mike/leaflet/ to get started, and everything was going great until I tried to shade in the Russian Federation. Its landmass spans non-contiguous tiles, and when I try to add a fill style to my #RUS path, it behaves anomalously. Example is here: http://dataviz.du.edu/projects/scratch/study_abroad.html
Example will take 1.5 s to render completely, it shades 3 countries, with the Russian Federation shading last.
This example uses a topojson file that I have used in other, pure d3 projects and have filled #RUS in those contexts without this issue.
Can anyone help? Thanks in advance.
This example uses a topojson file that I have used in other, pure d3 projects and have filled #RUS in those contexts without this issue.
You must be mistaken because your TopoJSON file is actually corrupt. See here an example with that file straight from your server: http://plnkr.co/edit/QOTwV3?p=preview Mind that i'm using plain TopoJSON and Leaflet's GeoJSON layer but it's yielding the exact same results.
PS. Is there any reason as to why you're using D3 for this? Asking because what i see you doing can be done just using Leaflet and TopoJSON, without D3. Here's a simple example:
function delay(features) {
var geojsonLayer = new L.GeoJSON(null, {
style: getStyle,
}).addTo(map);
var delay = 100;
features.forEach(function(feature) {
delay = delay + 100;
setTimeout(function() {
geojsonLayer.addData(feature);
}, delay);
});
}
var url = 'http://crossorigin.me/http://dataviz.du.edu/projects/scratch/worldnew.json';
$.getJSON(url, function(data) {
var geojsonData = topojson.feature(data, data.objects.test);
delay(geojsonData.features);
});

Proper way to set the StreetView PanoramaId and POV at the same time?

I have a little web app called StreetViewSafari which has a StreetViewPanorama and a Map on the screen and am having trouble determining how to set the PanoramaId(cam location) and POV(cam perspective) at the same time and have all the tiles load correctly. I've tried many different ways to do this and am currently settings the setOptions method.
As you can see on the site, the functionality between Firefox and Chrome are drastic. Chrome seems to load blotchy tiles which can be reproduced by using the "Show Next" button on the web app. Firefox has no problem loading the tiles.
I'd like to know if there is a better way that keep both browsers happy, or if I should escalate this issue to Google support.
For Example:
var options: google.maps.StreetViewPanoramaOptions = {
pano: loadedScene.panoId, //an id
pov: loadedScene.getStreetViewPov() //a valid POV object
};
panorama.setOptions(options);
Cheers,
Kevin
Basically:
although you call a single method(setOptions) this method will set the options one by one.
But as it seems the issue is the opposite, the options will be set too quick.
For me the result is much better when I set the pov again with a short delay(it seems to force a kind of re-rendering)
var options = {
pano: loadedScene.panoId,
pov: loadedScene.getStreetViewPov()
};
panorama.setOptions(options);
setTimeout(function() {
panorama.setPov(options.pov);
}, 500);

Categories

Resources