Cesium PinBuilder using "fromMakiIconId" - cesiumjs

I started using cesium for representing 3d maps and was trying to add Point of Interest data on top of this 3d view. I tried local png icons and it worked. I also realized can add icons from built in assets. I tried the below code and it worked perfect. I have a various set of PoIs but could not find the labels using which I can add them onto the map.
For example to add a hospital i referred hospital in the iconid.
var hospitalPin = Cesium.when(
pinBuilder.fromMakiIconId("hospital", Cesium.Color.RED, 48),
function (canvas) {
return viewer.entities.add({
name: "Hospital",
position: Cesium.Cartesian3.fromDegrees(77.311, 32.826),
billboard: {
image: canvas.toDataURL(),
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
},
});
}
);
In the similar way is there any reference for the icon Ids which I can use to make use of them in my code to represent the PoIs. Any help is appreciated.
I found the source images located at \Build\Cesium\Assets\Textures\maki from the cesium library which I think can be used.

The image you posted is from the PinBuilder docs, but check out the original source for that: It's a screenshot of the Cesium Sandcastle GeoJson Demo.
As you noticed, the images of the individual pins are stored in a folder called maki which has names like this:
airport.png
alcohol-shop.png
america-football.png
art-gallery.png
bakery.png
bank.png
bar.png
baseball.png
...
Just strip the .png off the end of the image filename, and that's it. That's the ID.
The dashes are allowed in the ID:
pinBuilder.fromMakiIconId("america-football", Cesium.Color.RED, 48)
But, the first few pins in the original screenshot don't have corresponding Maki icons, they're simple letters or numbers. You can build pins using text, using a different function, like this:
pinBuilder.fromText("A", Cesium.Color.RED, 48)
You may also use pins with Unicode characters on them.
pinBuilder.fromText("\u267b", Cesium.Color.RED, 48)
And finally, if you have a custom PNG file of your own, similar to a Maki icon but customized for your app's need, you may build a pin directly from the URL of the custom PNG file.
pinBuilder.fromUrl(url, Cesium.Color.RED, 48)

Related

Import Shapes of Custom Library from Draw.io in mxGraph

I'm currently working with the mxGraph library in javascript and I'm trying to create my own shapes in draw.io, to export them, then to reuse them as much as I want in my own program using the mxGraph library.
So far, I have tried to create a custom library, which contains all my shapes. I have exported it in XML which gives me a half-encoded XML file. Then, I'd like to import that mxLibrary in my own app so I can reuse these shapes for creating my own diagrams. I have no idea how to deal with that XML file.
I have also tried taking the XML from Extras -> Edit Diagram and reimport it with the codec, then with mxGraph#addCells but the shapes aren't grouped anymore, and I can't seem to find how to clone them.
My goal would literally to have my list of shapes/cells somewhere, which I can reuse whenever I want.
If this is not possible, how may I do that instead? I have also looked up how to create my own shapes (with redrawPath and the style thing), but it looks really long and boring.
Here's an example of what the XML looks like. The shape is a simple double square.
<mxlibrary>[{"xml":"xVNBbsIwEHyN78EugjOhcOqpLzDJgi05XstZSPJ7trFbiAqCqpV6sLQ7O2N7xrJQZdNvow7mDWtwQr0KVUZESlXTl+CckIWthVoLKQteQm7uTGfjtAg6gqdnBDIJTtodISEJaGlwGThEPIZMg0jQT46q0HuoSO8+6cX3K4zUfP4WsAGKA1M6W5NJjGVWGbAHQ1NMt/keX8qLHy6ypdv21GN7nbEE70FXH33HDyHUylDDO65nXOo2sD1u9rYH3nV1N4lrx/LfHL/8veO9da5Eh5Exjx5+GUIWzJNgmHRXAS1uBLT4eUDcXn7TOJt8tjM=","w":80,"h":80,"aspect":"fixed","title":"custom_shape_1"}]</mxlibrary>
Thank you in advance!
There are 2 ways I know, to do it, depending on your needs.
Embed draw.IO as an iframe in your app, and create a plugin that adds your own palette of icon on the side bar. you can watch the p1 plugin code, and replicate it plugin list in draw.io, look for the p1 plugin
. code example of how to integrate draw.io in your app
hint: if pulgins are not loaded, check the plugin folder link.
If you add the vertices on you own app, create your own style, and reuse it when creating.
updateStyles()
{
var style = new Object();
style[(<any>window).mxConstants.STYLE_SHAPE] =
(<any>window).mxConstants.SHAPE_IMAGE;
style[(<any>window).mxConstants.STYLE_PERIMETER] =
(<any>window).mxPerimeter.RectanglePerimeter;
style[(<any>window).mxConstants.STYLE_IMAGE] =
'../assets/transformer.png';
style[(<any>window).mxConstants.STYLE_FONTCOLOR] = '#000000';
style[(<any>window).mxConstants.STYLE_WHITE_SPACE] = 'wrap';
style[(<any>window).mxConstants.STYLE_VERTICAL_ALIGN] = 'bottom';
this.graph.getStylesheet().putCellStyle('transformer', style);
}
reuse this style whenever creating a vertex using insertVertex function.
try {
const parent = this.graph.getDefaultParent();
this.graph.getModel().beginUpdate();
const vertex = this.graph.insertVertex(parent, uuid.v4(), node, 40, 40, 80, 40, 'transformer');
} finally {
this.graph.getModel().endUpdate();
}

how to change a CesiumJS viewer's baselayer url

i am using a CesiumJS instance to display a base map of the earth using a imageryProvider from source A.
var viewer = new Cesium.Viewer('cesiumContainer', imageryProvider:providerA);
Now while using the Viewer I would like to be able to change this map to get images from providerB at a certain event.
I tried:
viewer.scene.imageryLayers.get(0).imageryProvider.url = providerB.url
However that does not seem to work and also feels quite like hack anyway.
I could not find anything in Cesium's documentation .
Is this at all possible without restarting / recreating the viewer instance?
I know that there is a Cesium.BaseLayerPicker (https://cesium.com/docs/cesiumjs-ref-doc/BaseLayerPicker.html)
However I do not see what method this picker calls on "select" )
Thanks a lot.
The BaseLayerPicker widget calls this code when the user selects a new layer.
There's a lot of boilerplate widget management in that block of code, but for your sake, only a couple of the lines are critical. First, the old existing active imagery layer is searched for, and removed:
imageryLayers.remove(layer);
Then, a new imagery provider is constructed and added at index 0, the first position, which is the base imagery layer:
imageryLayers.addImageryProvider(newProviders, 0);
You can directly change the URL of the provider but you should also change appropriate parameters("layers" in case of WMS, "layer", "style", "format", "tileMatrixSetID " ... in case of WMTS) depending on the type of provider(WMS or WMTS).

WebGL - change mapAmbient material property in Three.js

I'm trying to update an image in a material of a pre-loaded .js model - i want it to have the same properties, whereas only the image is changed.
Was trying to use this post as a reference, but in the .js model file, the map appears as the "mapAmbient" property. I was thinking of somehow using the THREE.ImageUtils.loadTexture() function, but couldn't find where exactly it should be placed.
Moreover, the texture should be loaded using an Image() object generated using another canvas. Any help would be appriciated
*Edit:
Wasn't able to find actual way to change that property in runtime, but was able to change the image using base64 encoding:
//img is base64 encoded image
var tex = new THREE.ImageUtils.loadTexture(img);
currentMesh.material.materials[1].map = tex;

How can I use a sprite to specify the pushpin png I want to use in a map?

After (probably) deciding on the jQuery map plugin to use (see What jQuery map plugin allows specifying the color of the pushpins?), I now need png files of colored pushpins.
I found a dandy one here: http://www.fuzzimo.com/free-vector-post-it-notes-push-pins/ :
...but it appears to be, not a collection of various png files I can use (blue.png, red.png, chartreuse.png, etc.) but one humongous .png file with an array of images. So I'm guessing this is meant to be used as a sprite. Being a sprite newby, though, I don't know how to use this image and specify the section of it that I want to use.
Specifically, the jQuery code I'll be using to set the marker's icon is like:
icon: '../img/apartment.png'
...how can I specify usage of a specific pushpin?

Stick Images together

I just tried to use Google Map Buddy to get satellite image from Google Map. This application first download small images from google map and then stick them together into new image. I had to wait about 2 hours to get images download my computer and it looks like it downloaded all images (22,194 images) but then the app told me that it cannot stick them together. When I started app again I though this app will reuse images on my comp but it start downloading them again. So I had to stop the process and ask you, guys, if you know how I can put that puzzle together.
The naming pattern of those images goes like this:
x=92651y=48130zoom=17.png
x=92652y=48130zoom=17.png
x=92653y=48130zoom=17.png
x=92654y=48130zoom=17.png
x=92655y=48130zoom=17.png
...
...
x=92664y=48131zoom=17.png
x=92665y=48131zoom=17.png
x=92666y=48131zoom=17.png
x=92667y=48131zoom=17.png
...
...
x=92689y=48132zoom=17.png
x=92690y=48132zoom=17.png
x=92691y=48132zoom=17.png
x=92692y=48132zoom=17.png
x=92693y=48132zoom=17.png
What can I do to stick them together programmatically using some simple scripting language? I have access to Mac and Windows systems and may be can install any simple scripting languages.
Thanks
You could use Python with Python Imaging Library (PIL).
First I'd make a list of filename and their coordinates. Extract the integer coordinates from the filenames with regular expressions and store them in a list of dictionaries:
>>> filename = 'x=92664y=48131zoom=17.png'
>>> imagePattern = re.compile(r'^x=(\d{5})y=(\d{5})zoom=17.png$')
>>> x,y = map(int, imagePattern.search(filename).groups())
>>> {'x':x, 'y':y, 'filename':filename}
{'y': 48131, 'x': 92664, 'filename': 'x=92664y=48131zoom=17.png'}
Having a list of dictionaries enables you to sort them according to either dimensions:
tileListSortedByX = sorted(tileList, key = lambda i: i["x"])
and also filter them:
fileListWhereX48131 = [tile for tile in tileList if tile["x"]==48131]
With these two operations you can easily imagine the for loops to iterate over tiles line by line.
The last thing you need to create a big empty image (with PIL) where you'll paste the small tile images into. Its size will be a multiple of the tile size.
>>> from PIL import Image
>>> bigImage = Image.new('RGB',(300,300),(255,255,255))
#creates a white 300x300 image
Pasting the small images into the big one looks like this:
>>> smallImage = Image.open(tile["filename"])
>>> bigImage.paste(smallImage,(0,0))
Hope you get the idea.
The process of "sticking images together" is usually called "stitching" or "mosaicing".
I found a list of many applications that do this on Wikipedia article - "Comparison of Photo Stitching Applications".
Edited: removed link to single app I found and replaced with wikipedia list of software.