make circles(buffers?) on openlayers - geometry

I am sorry for the awkward grammar because I am not good at English.
I want to make circles at each point(load from url)
I used ol.source.imageWMS, but i don't know how to get each point's latitude, longitude.
this is my code:
Source_PtSearch = new ol.source.ImageWMS({
url : 'http://localhost:9090/geoserver/HB/wms',
params : {'LAYERS' : 'HB:HB_ASF_TEST2'},
serverType : 'geoserver',
crossOrigin : 'anonymous',
projection : 'EPSG:4326'
});
how can i get each point's latitude, longitude?

First make a GetFeatureInfo request to your Geoserver to retrieve all features from a WMS layer. Then have a look at WMS GetFeatureInfo Example to see how to parse the response to get all Features, in resume it's:
var allFeatures = new WMSGetFeatureInfo().readFeatures(response);
Then you can iterate over all features and get the coordinates by:
feature.getGeometry().getCoordinates()

Related

How do I query the vimeo api for a specific video title?

Hi I'm querying for a specific video by title - and at the moment I get mixed results.
my videos are all named with a consecutive number at the end ie ANDNOW2022_00112, ANDNOW2022_00113 etc
When I search /videos/?fields=uri,name&query=ANDNOW2022_00112 I get all of the videos returned
I've also tried the query_fields using
/me/videos?query_fields=title&sort=alphabetical&query=ANDNOW2022_00112
I just want the one I've searched for - or a no results returned.
At the moment I get all of the videos with AN2022 in the title/name. Now 'usually' the one I searched for is at the top of the list but not everytime.
Any tips appreciated.
Okay I'm not going mad :)
This is from Vimeo and is here for those with the same issue - basically to get t to work you need to understand that:
After speaking with our engineers, the current search capability are not "Exact" search.
When adding numbers or underscores the search is split into parts so "ANDNOW2022_00112" is transforming the query into the parts "andnow2022", "andnow", "2022", and "00112". So this is why your seeing these results. Our engineering team are in the process of improving the search capabilities and hope to provide a release in the near future.
Which means for now I'll have to rename my files.
Preface:
Vimeo does not currently offer an API endpoint for exact title search — but even if it did — it's possible to upload multiple videos and assign them identical titles. There's no way to use the API to positively identify a video by title — this is why every uploaded video is assigned a unique ID.
Solution:
Because the API returns data which includes an array of video objects, you can solve this problem in the same way you'd solve any similar problem in JavaScript where you have to find an element in an array: Array.prototype.find()
Here's how you can apply it to your problem:
Query the API using the parameters you described in your question.
You might also be interested in using the sort and direction parameters for greater control over a deterministic sort order.
Find the first item in the returned array of video objects that match your expected text exactly, and return it (or undefined if it doesn't exist)
Here's a code example with some static data from the API that was used to search for the video Mercedes Benz from the user egarage — note that I've omitted quite a few (irrelevant) fields from the response in order to keep the example small:
// Mocking fetch for this example:
function fetch (_requestInfo, _init) {
const staticJson = `{"total":2,"page":1,"per_page":25,"paging":{"next":null,"previous":null,"first":"/users/egarage/videos?query_fields=title&query=Mercedes%20Benz&sort=alphabetical&direction=asc&page=1","last":"/users/egarage/videos?query_fields=title&query=Mercedes%20Benz&sort=alphabetical&direction=asc&page=1"},"data":[{"uri":"/videos/61310450","name":"50th Anniversary of the Pagoda SL -- Mercedes-Benz Classic Vehicles","description":"Penned by designer Paul Bracq, the W113 SL had big shoes to fill: it had the incredible task of succeeding the original and instantly iconic 300 SL Gullwing. But you can't copy a legend, so Bracq designed one of his own. Straight lines replaced curves and a low-slung roof was replaced by a high top design that gave the car its nickname: the Pagoda.\\n\\nMUSIC: Developer Over Time","type":"video","link":"https://vimeo.com/61310450"},{"uri":"/videos/55837293","name":"Mercedes Benz","description":"To celebrate Mercedes Benz 125th birthday, the 2011 Pebble Beach Concours d’Elegance showcased the models that trace the lineage to Benz and Daimler —particularly Mercedes-Benz. This tribute chronicled early racing greats, coachbuilt classics, and preservation cars. Produced in association with DriveCulture.","type":"video","link":"https://vimeo.com/55837293"}]}`;
return Promise.resolve(new Response(staticJson));
}
async function fetchVideoByTitle (token, userId, videoTitle) {
const url = new URL(`https://api.vimeo.com/users/${userId}/videos`);
url.searchParams.set("query_fields", "title");
url.searchParams.set("query", videoTitle);
url.searchParams.set("sort", "alphabetical");
url.searchParams.set("direction", "asc");
const headers = new Headers([
["Authorization", `Bearer ${token}`],
]);
const response = await fetch(url.href, {headers});
const parsedJson = await response.json();
// Find the video that matches (if it exists):
const maybeFirstVideoObj = parsedJson.data.find(video => video.name === videoTitle);
return maybeFirstVideoObj;
}
async function main () {
const video = await fetchVideoByTitle(
"YOU_ACTUAL_TOKEN",
"egarage",
"Mercedes Benz",
);
console.log(video); // {name: "Mercedes Benz", link: "https://vimeo.com/55837293", ...}
}
main();

map marker in script tags within ejs file not showing

I want to have two markers, one of the user's current location and the other will be the location of post in my app. The marker of the user's current location is plotted on the map but not the marker belonging to the location of a post. Post contains information of a place of interest with latitude and longitude pair.
I rendered an ejs view with post like this:
router.get('/posts/:id', function(req,res) {
db.post.findOne({
where: { id: req.params.id}
}).then(function(post) {
res.render('posts/post_detail', {post: post})
});
});
post contains latitude and longitude information that I want to access to plot a marker on my leaflet map. I place script tags at the bottom of the ejs view like this:
<script>
var post = <%- JSON.stringify(post) %>;
console.log(post.latitude);
console.log(post.longitude);
L.marker([post.latitude, post.longitude]).addTo(map);
console.log(map)
</script>
Both latitude and longitude are printed out on the console with the same values as in the database. I used the same L.marker code elsewhere to place markers on my map and it works perfectly fine but not in this case. I am getting --
Uncaught TypeError: t.addLayer is not a function error <--
Is there another way around where I can access the latitude and longitude values to plot a marker on the map?
The map is not defined in the scope of that script tag.

Google Maps - KML Layer Not Appearing on Map

I'm having an issue where my KML Layer does not appear on an embedded google map on my website.
I made a free website using google sites and uploaded my KML file to it so that I could set the url: 'https://sites.google.com/site/kmlroute/home/kml'. The google map itself shows up but the KML layer at that url does not.
My code is below. Does anyone see any syntax errors, logic errors, or anything of the sort that would be stopping my KML Layer from appear on my map???
Any comments, help, and advice is welcome and sincerely appreciated.
function initMap(lat, lng) {
var myLatLng = {lat: lat, lng: lng};
// Create a map object and specify the DOM element for display.
var map = new google.maps.Map(document.getElementById('bus_1_map'), {
center: myLatLng,
scrollwheel: false,
zoom: 12
});
var route = new google.maps.KmlLayer({
url: 'https://sites.google.com/site/kmlroute/home/kml',
map: map
});
You need to pass the URL of the XML file itself.
Try this:
var route = new google.maps.KmlLayer({
url: 'https://sites.google.com/site/kmlroute/home/kml/Bus%2022%20Route.kml.xml?attredirects=0&d=1',
map: map
});
How did I the url?
Go to https://sites.google.com/site/kmlroute/home/kml
Copy link address of the download arrow.

JointJs creating custom shapes and specifying their default link

I'm trying to implement my own shape class with ports. However I want the links that these shapes generate to be smooth. Right now, the only way i know to make smooth links is
link.set('smooth', true).
But how do i do that not through code? How do i get smooth links by just dragging?
I extended Link class (MyLink) but how do i tell JointJS which Link class to use when i drag on the port?
joint.shapes.myclass.Link = joint.dia.Link.extend({
defaults: {
type: 'myclass.Link',
attrs: { '.connection' : { 'stroke-width' : 5 }},
smooth:true
}
});
Links created via the UI by dragging ports are defined in the defaultLink property of the paper. It can either be an object in which case it is a link model or a function that returns a link model:
var paper = new joint.dia.Paper({
defaultLink: new joint.shapes.myclass.Link,
...
})
or:
var paper = new joint.dia.Paper({
defaultLink: function(elementView, magnet) {
if (aCondition) return new joint.dia.Link;
else return joint.shapes.myclass.Link;
}
})
The function gives you flexibility in creating different links on the fly depending on what element is underneath or what magnet (SVG element for port) is being dragged.

How do I optimize the loading time of Google Earth Web Plugin if I have a very large KML file?

My client has a very large KML file, it contains around 6000+ placemarks and these placemarks have to appear as 3D models on the map. What's even worse is that the KML file does not contain that <link> tag for the COLLADA file, which means I have to traverse the KML file and attach a COLLADA file before it can be displayed on google earth. Now I can already traverse and add a 3D model for each placemark. I tested it with a very small KML file(which contains like less than 100 placemarks) and it worked great as expected...but when I used the very large KML file which had like 6000+ placemarks on it, the plugin just crashes and I am advised to refresh the browser, only to find it crashing again... :(
Any advice on this?
Is there a limit to the number of placemarks I can put on google earth web plugin?
How do I make the loading faster?
function render3DPoles(polesKmlLink){
google.earth.fetchKml(ge,polesKmlLink, function(object){
if(object){
var item = object.getFeatures().getChildNodes().item(0);
var folder = item.getFeatures().getChildNodes();
var latitude;
var longitude;
for(var i = 0; i<folder.getLength(); i++){
var placemark = folder.item(i);
latitude = placemark.getGeometry().getLatitude();
longitude = placemark.getGeometry().getLongitude();
var model = ge.createModel('');
var location = ge.createLocation('');
model.setLocation(location);
var link = ge.createLink('');
link.setHref('insert URL of collada file here');
model.setLink(link);
location.setLatitude(latitude);
location.setLongitude(longitude);
model.setLocation(location);
placemark.setGeometry(model);
ge.getFeatures().appendChild(placemark);
}
var la = ge.createLookAt('');
la.set(latitude,longitude, 25, ge.ALTITUDE_RELATIVE_TO_GROUND,180, 60, 100);
ge.getView().setAbstractView(la);
} else {
setTimeout(function() {
alert('Bad or null KML.');
},0);
}
});
}
I have dealt with dealing 10,000s of placemarks and other kml objects in the earth plugin and the best way I find is manage the data in a javascript object. dealing with them in standard kml would often crash things.
parse the kml before hand into something that you can handle as an object
start with:
var myModels = {};
for adding the first item if the id is 'foo' or a numeric do something like:
myModels['foo'] = {
description: 'some description for foo',
longitude: 100.12345,
latitude: 45.4567
linkUrl: 'http://mydomain.com/mymodels/foo.dae',
kmlObject: null};
now looking at the code from:
http://code.google.com/apis/ajax/playground/?exp=earth#creating_3d_models
you will have something similar to:
var placemark = ge.createPlacemark('');
placemark.setName('model');
var model = ge.createModel('');
.......
placemark.setGeometry(model);
now go:
myModals['foo'].kmlObject = placemark;
this will give you a quick reference to the model if you need to change it or remove it with just
myModels['foo'].kmlObject
no need to traverse the tree again.
one thing I found to be faster was to define kml client side and use parseKml to load it rather then create individual objects and add them.
also you can build in logic to only add the dae model that are within the area the user is looking at
to loop through all the items
var i, iModel;
for (i in myModels){
iModel = myModels[i];
if(myModels[m].kmlObject == null){
'add if statement to check if the models long/lats are in current view with
' iModel.longitude, iModel.latitude
}
}
also rather than add everything in one operation, add 10-20 model in a single batch and use setTimeout to start another batch operation a second later and leverage .executeBatch
https://developers.google.com/earth/documentation/reference/google_earth_namespace#ab26414915202d39cad12bcd5bd99e739
While there's no technical limit, the more you add the more resources get used. Depending on the complexity of your models and other data, you will be able to add more or less, but 6000 is quite a lot of to display at once even for simple markers.
One solution for a large/complex KML is to create regionated KMLs instead, such that you are loading just the data you need at any given time, based on visible regions (see http://code.google.com/apis/kml/documentation/regions.html )

Resources