I'm trying to display a heatmap over the globe in Cesium but the globe isn't even showing up on the screen, only the background is. I looked in the network part of google chrome and it shows the actual image I need being loaded from the server.
<script>
var count=0;
var viewer = new Cesium.CesiumWidget('cesiumContainer');
var layers = viewer.scene.imageryLayers;
var imageArray = <?php echo json_encode($images) ?>// PARSING PHP ARRAY INTO JAVASCIPT
alert(imageArray[0]);
var date;var name='HeatMap-2006-01-16.png'; //FOR INITAL PAGE LOAD
loadCesium();
function loadCesium()
{
//Cesium Active Window
layers.addImageryProvider(new Cesium.SingleTileImageryProvider({
url : 'images/'.concat(name),
rectangle : Cesium.Rectangle.fromDegrees(-180.0, -90.0, 180.0, 90.0)
}));
}
function overlayChange()
{
name = imageArray[count];
for (i = 0; i < name.length; i++)
{
if(name.charAt(i)=="-")
{
date = name.substring(i);
break;
}
}
loadCesium();
count = count + 1;
}
function overlayChangeBack()
{
if(count == 0)
{
count = 39;
name = 'HeatMap';
name = name.concat(count.toString());
loadCesium();
}
else
{
name = 'HeatMap';
count=count-1;
name = name.concat(count.toString());
loadCesium();
}
}
</script>
Right now I'm just trying to display the name variable('HeatMap-2006-01-16.png') for the initial image but it's not displaying. No image I try to put instead displays either so it's definitely an issue with cesium.
I'm not sure why this fixed it because I've had it working without this statement but when declaring the cesiumContainer in the variable viewer, you have to set it as this:
var viewer = new Cesium.CesiumWidget('cesiumContainer', {
imageryProvider : new Cesium.ArcGisMapServerImageryProvider({
url : 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer'
}),
baseLayerPicker : false
});
Related
I am having two viewers in my application and want both of them to orbit the same with the same positions and camera angles and also follow the same while zooming in and out.
Is there any way?
I've applied the below solution but it's delayed by one second.
viewer2.addEventListener(Autodesk.Viewing.CAMERA_CHANGE_EVENT, function()
{
if(!viewer1CameraChangeMutex) {
clearTimeout(viewer2CameraChangeMutex);
viewer.restoreState(viewer2.getState());
viewer2CameraChangeMutex=setTimeout(function(){viewer2CameraChangeMutex=undefined},1000)
}
});
viewer.addEventListener(Autodesk.Viewing.CAMERA_CHANGE_EVENT, function()
{
if(!viewer2CameraChangeMutex) {
clearTimeout(viewer1CameraChangeMutex);
viewer2.restoreState(viewer.getState());
viewer1CameraChangeMutex=setTimeout(function(){viewer1CameraChangeMutex=undefined},1000)
}
});
You can stop unnecessary event ping-pong b/w viewers, e.g. change view on viewer1 --> change event on viewer 1 then set view state to viewer2 --> change event on viewer 2 then change viewer 1 state --> change event on viewer 1 ....., by comparing viewport status and set view status to other viewer only when viewport status is not in same status.
Below is example code snippet for above explanation.
function compare(stateA, stateB)
{
var viewportA = stateA["viewport"] || {};
var viewportB = stateB["viewport"] || {};
//compare all members of viewportA and viewportB, return true when all members are same.
if( viewportA["name"] !== viewportB["name"] ||
viewportA["projection"] !== viewportB["projection"] ||
viewportA["isOrthographic"] !== viewportB["isOrthographic"] ||
.......//compare all other members of viewport.
//Please note you need to afforded small numeric error for numeric value comparison.
)
{
return false;
}
return true;
}
var sfilter = {
viewport: true
};
viewer3d1.addEventListener(Autodesk.Viewing.CAMERA_CHANGE_EVENT, function () {
var v1state = viewer3d1.getState(sfilter);
var v2state = viewer3d2.getState(sfilter);
if (!compare(v1state, v2state)) {
viewer3d2.restoreState(viewer3d1.getState(sfilter), sfilter, true);
}
});
viewer3d2.addEventListener(Autodesk.Viewing.CAMERA_CHANGE_EVENT, function () {
var v1state = viewer3d1.getState(sfilter);
var v2state = viewer3d2.getState(sfilter);
if (!compare(v1state, v2state)) {
viewer3d1.restoreState(viewer3d2.getState(sfilter), sfilter, true);
}
});
I scenario is below :
map is shown under from TiledWMS layer from mapserver. It has 2 layers.
TiledWMS layer for OSM world map.
TiledWMS layer for layers defined in kml file placed in mapserver through .map file. This map file contains many layers.
Now , when user click on map : it got 2 layers as above.
But since 2nd layer is made up of different layers as given in .map file , i am not able to uniquely identify these layers. I want that since 2 nd layer is made up of different layers in kml file i should be able to uniquely identify them on mouse click or hower.
Thanks
Satpal
I am able to get it : below is samaple code for others.
var coord = evt.coordinate;
var pixel = $scope.map.getPixelFromCoordinate(coord);
var viewProjection = $scope.map.getView().getProjection();
var viewResolution = $scope.map.getView().getResolution();
var numberOfLayersOnMap = $scope.map.getLayers();
var feature = $scope.map.forEachFeatureAtPixel(pixel, function(feature, layer){return feature;}, null, function(layer) {return true;});
if(feature === undefined)
{
$scope.map.forEachLayerAtPixel(pixel, function (layer)
{
if(!layer)
{
return ;
}
var urlWMSGetFeatureInfo = layer.getSource().getGetFeatureInfoUrl(coord, viewResolution, viewProjection, {
'INFO_FORMAT': 'application/vnd.ogc.gml'
});
if(urlWMSGetFeatureInfo.indexOf("osm-google.map")<0)
{
$http({
method: 'GET',
url: urlWMSGetFeatureInfo,
}).success(function(data){
var parser = new ol.format.WMSGetFeatureInfo();
var features = parser.readFeatures(data);
if(features.length>0)
{
var featureName = features[0].n.Name;
topOverlayElement.innerHTML = featureName;
$scope.highlightOverlay.setFeatures(new ol.Collection());
if($scope.flagLinkage == true)
{
var xmlObj = utility.StringToXML(data);
var xmlDocumnet = xmlObj.childNodes[0];
var layerNode = xmlDocumnet.children[0];
var gmlLayerNode = layerNode.children[0];
var layerName = gmlLayerNode.textContent;
var layerInfoObject = {};
layerInfoObject.layerName = layerName;
//layerInfoObject.placemarkName = featureName;
$scope.placemarksSelectedObject.push(layerInfoObject);
$scope.placemarksSelectedFeatureObject.push(features[0]);
}
else
{
$scope.placemarksSelectedFeatureObject.length = 0;
$scope.placemarksSelectedFeatureObject.push(features[0]);
}
$scope.highlightOverlay.setFeatures(new ol.Collection($scope.placemarksSelectedFeatureObject));
var featureDescription = features[0].n.description;
middleOverlayElement.innerHTML = (featureDescription === undefined) ? '' : featureDescription;
$scope.showOverlay(coord);
}
}).error(function (data) {
console.log("Not able to get capabilty data.");
});
}
else
{
$scope.closeOverlay(evt);
}
});
I have used Google Places API in order to display various places. I want at a time to display 20 places and when user scrolls the table view and reaches last field I want to add the rest of data and so on. I have created a function which returns the view and works perfectly excluding one thing. When further data is not available then it goes on loading the last data which is already loaded. Here goes my code.
Ti.include('Functions/get_lat_long.js');
var myTable = Ti.UI.createTableView();
var next_page;
var nxt_pge_tkn;
var tableData = [];
function json_parsing(url,firsttime,winloading)
{
var view1=Ti.UI.createView({
//height : '100%',
width : '100%',
backgroundColor : '#EDDA74',
top : '10%',
borderColor : "black"
});
//For storing url in case next_page_token variable is invalid
var curloc=Ti.App.Properties.getString("curlocation");
//calling method in order to retrive latitude and longitude of current location
get_latitude_longitude(curloc);
//setting the base url that have been initialized in global.js file
var baseurl=Ti.App.Properties.getString("preurl");
//storing lat and lng file that have been initialized in get_lat_lon.js file get_latitude_longitude function
var lat=Ti.App.Properties.getString("curlat");
var lng=Ti.App.Properties.getString("curlng");
//Storing radius which have been initialized in global.js file
var radiusmts=Ti.App.Properties.getInt("curradius")*1000;
//setting location type from the value that have been selected in app.js file by user
var loc_type=Ti.App.Properties.getString("curcategory");
//fetching and storing key which have been initialized in global.js file
var key=Ti.App.Properties.getString("apikey");
if(firsttime==true)
{
winloading.open();
var completeurl=baseurl+lat+","+lng+"&radius=" + radiusmts+ "&types=" + loc_type+ "&sensor=false&key=" + key;
}
else
{
winloading.show();
var completeurl=url;
}
var client = Ti.Network.createHTTPClient();
Ti.API.info("complete url " +completeurl);
client.open('GET',completeurl);
client.onload = function(e) {
//For getting next_page_token so that next page results could be displayed
var json = JSON.parse(this.responseText);
if(json.next_page_token)
{
Ti.API.info("Next page token found ");
next_page=true;
nxt_pge_tkn=json.next_page_token;
}
else
{
Ti.API.info("Next page token not found ");
next_page=false;
}
if(json.results.length==0)
{
var lblno_record=Titanium.UI.createLabel({
text : "No Record Found",
color : "black",
font : {fontSize : "25%" }
});
view1.add(lblno_record);
}
else
{
for(var i=0; i <json.results.length;i++)
{
//Ti.API.info("Place " + json.results[i].name+ " Lat " + json.results[i].geometry.location.lat + " Lng " + json.results[i].geometry.location.lng);
var row = Ti.UI.createTableViewRow({
className : "row"
//height : "80%"
});
//For temporary storing name in name variable
var name=json.results[i].name;
//Logic for shortening string in order to avoid overlapping of string
(name.length>35)?name=name.substr(0,34)+ "..." :name=name;
//Create label for displaying the name of place
var lblname=Ti.UI.createLabel({
//text : json.results[i].name,
text : name,
color : "black",
font : {fontSize : "20%"},
left : "22%",
top : "5%"
});
Ti.API.info("Name :- " + name);
row.add(lblname);
var add= json.results[i].vicinity;
(add.length>125) ? add=add.substr(0,123)+ ". ." : add=add;
var lbladdress=Ti.UI.createLabel({
text : add,
color : "black",
font : {fontSize : "15%"},
left : "22%",
top : "30%",
width : "71%"
});
row.add(lbladdress);
var imgico=Ti.UI.createImageView({
image : json.results[i].icon,
height : "90",
width : "90",
left : "1%",
top : "3%"
//bottom : "10%"
});
row.add(imgico);
tableData.push(row);
}
//setting data that have been set to mytable view
myTable.setData(tableData);
view1.add(myTable);
}
winloading.hide();
};
client.onerror=function(e){
alert("Network Not Avaliable");
};
myTable.addEventListener('scroll',function(e){
var first=e.firstVisibleItem;
var visible=e.visibleItemCount;
var total=e.totalItemCount;
Ti.API.info("Value of next_page_token before loop " + next_page);
if(next_page==true && first+visible==total )
{
Ti.API.info("Value of next_page_token in loop " + next_page);
var newurl="https://maps.googleapis.com/maps/api/place/nearbysearch/json?pagetoken="+nxt_pge_tkn+"&sensor=false&key="+key;
firsttime=false;
winloading.show();
//myTable.removeEventListener('scroll',function(e){});
json_parsing(newurl,firsttime,winloading);
//get_next_page(newurl);
}
});
client.send();
return view1;
client.clearCookies();
}
I was looking through your code and I would like to point:
There is an important issue with the block:
myTable.addEventListener('scroll',function(e){
...
});
this block is called each time you call your json_parsing function. Because of that you will have several functions attached to myTable scroll event. I'm sure that this isn't your intention. You should put it out of json_parsing.
About your specific issue you could try to look at the json.next_page_token value in your client.onload function:
client.onload = function(e) {
//For getting next_page_token so that next page results could be displayed
var json = JSON.parse(this.responseText);
Ti.API.info(JSON.stringify(this.responseText);
if(json.next_page_token)
{
...
maybe the value is an empty object {} or a 'false' string that will return a thruthy value. Don't forget that in javascript there are only 6 falsy values: false, undefined, null, 0, '' and NaN.
In practice this is a minor issue, but in documentation HTTPClient.onload and HTTPClient.onerror functions must be set before calling HTTPClient.open function
BTW, you have unreachable code at the end of your json_parsing function, but I think you already know that :-)
client.send();
return view1;
client.clearCookies(); //Unreachable code
I am quite new to Openlayers and was wondering if there is a method or event that returns the zooming direction, e.g. onzoomin/onzoomout events. I am using sproutcore 1.0 and trying to modify a feature font according to the zooming level. I tried working with Rules but according to the application structure this does not work. Here is my sample event of what I want to do:
this.map.events.on({ "zoomend": function (e) {
var sub = 0;
if (ZOOMOUT){
sub = this.getZoom();
} else {
sub = this.getZoom() * -1;
}
var font = myFeature.layer.styleMap.styles['default'].defaultStyle.fontSize;
font = font + sub*10;
myFeature.layer.redraw();
}});
Found a workaround using geometry bounds which gives a good result:
this.map.events.on({ "zoomend": function (e) {
var width = myFeature.geometry.bounds.right - myFeature.geometry.bounds.left;
var div = 0;
if (this.getZoom() > 12) {
div = 4;
} else {
div = 6;
}
myFeature.layer.styleMap.styles['default'].defaultStyle.fontSize = (width/((15 - this.getZoom())+1)) / div).toString() + "px";
myFeature.layer.redraw();
}});
I need to create something like this:
http://www.mrporter.com/journal/journal_issue71/2#2
where every product in my big image is associated with a tooltip which appears on mouse hover.
But I need this to work with fullscreen images.
The first solution I thought (as the example above) is the map html solution where each fill up exactly the boundaries of my products.
The problem is that I can't indicate precise values for my because my image size depends on window screen.
The best solution would be the possibility to set percentage values for my area.
Is this possible? Any other suggestions ?
Alternative solution using links:
CSS:
.image{
position: relative;
}
.image a{
display: block;
position: absolute;
}
HTML:
<div class="image">
<img src="image.jpg" alt="image" />
</div>
Percentage dimensions can be detected in graphic editors
There is a jQuery plugin for this jQuery RWD Image Maps.
You might want to integrate my pending pull request (manually) to support "width=100%": https://github.com/stowball/jQuery-rwdImageMaps/pull/10
you can check this this plugin is life saving.
Useful when you want to map a percentage scaled image etc.
It can be used with or without jQuery.
https://github.com/davidjbradshaw/imagemap-resizer
and you can see it working at.
http://davidjbradshaw.com/imagemap-resizer/example/
Because this can't be done with simple HTML/CSS manipulation, the only alternative is JavaScript to, effectively, recalculate the coordinates based on the resizing of the image. To this end I've put together a function (though there's two functions involved) that achieves this end:
function findSizes(el, src) {
if (!el || !src) {
return false;
}
else {
var wGCS = window.getComputedStyle,
pI = parseInt,
dimensions = {};
dimensions.actualWidth = pI(wGCS(el, null).width.replace('px', ''), 10);
var newImg = document.createElement('img');
newImg.src = src;
newImg.style.position = 'absolute';
newImg.style.left = '-10000px';
document.body.appendChild(newImg);
dimensions.originalWidth = newImg.width;
document.body.removeChild(newImg);
return dimensions;
}
}
function remap(imgElem) {
if (!imgElem) {
return false;
}
else {
var mapName = imgElem
.getAttribute('usemap')
.substring(1),
map = document.getElementsByName(mapName)[0],
areas = map.getElementsByTagName('area'),
imgSrc = imgElem.src,
sizes = findSizes(imgElem, imgSrc),
currentWidth = sizes.actualWidth,
originalWidth = sizes.originalWidth,
multiplier = currentWidth / originalWidth,
newCoords;
for (var i = 0, len = areas.length; i < len; i++) {
newCoords = areas[i]
.getAttribute('coords')
.replace(/(\d+)/g,function(a){
return Math.round(a * multiplier);
});
areas[i].setAttribute('coords',newCoords);
}
}
}
var imgElement = document.getElementsByTagName('img')[0];
remap(imgElement);
JS Fiddle demo.
Please note, though, that this requires a browser that implements window.getComputedStyle() (most current browsers, but only in IE from version 9, and above). Also, there are no sanity checks other than ensuring the required arguments are passed into the functions. These should, though, be a start if you want to experiment.
References:
document.body.
document.createElement().
document.getElementsByName().
document.getElementsByTagName().
element.getAttribute().
element.setAttribute().
element.style.
Math.round().
node.appendChild().
node.removeChild().
parseInt().
string.replace().
string.substring().
window.getComputedStyle.
Percentages in image maps are not an option. You might want to get some scripting involved (JS) that recalculates the exact position on images resize. Of course, in that script you can work with percentages if you want.
Consider using the Raphaël JavaScript Library with some CSS. See http://raphaeljs.com/ and Drawing over an image using Raphael.js.
I know this is an old question but maybe someone needs this at some point as I did. I modified #David Thomas' answer a bit to be have this little piece of JS be able to handle future recalculations:
function findSizes(el, src) {
if (!el || !src) {
return false;
}
else {
var wGCS = window.getComputedStyle,
pI = parseInt,
dimensions = {};
dimensions.actualWidth = pI(wGCS(el, null).width.replace('px', ''), 10);
var newImg = document.createElement('img');
newImg.src = src;
newImg.style.position = 'absolute';
newImg.style.left = '-10000px';
document.body.appendChild(newImg);
dimensions.originalWidth = newImg.width;
document.body.removeChild(newImg);
return dimensions;
}
}
function remap(imgElem) {
if (!imgElem) {
return false;
}
else {
var mapName = imgElem
.getAttribute('usemap')
.substring(1),
map = document.getElementsByName(mapName)[0],
areas = map.getElementsByTagName('area'),
imgSrc = imgElem.src,
sizes = findSizes(imgElem, imgSrc),
currentWidth = sizes.actualWidth,
originalWidth = sizes.originalWidth,
multiplier = currentWidth / originalWidth,
newCoords;
for (var i = 0, len = areas.length; i < len; i++) {
// Save original coordinates for future use
var originalCoords = areas[i].getAttribute('data-original-coords');
if (originalCoords == undefined) {
originalCoords = areas[i].getAttribute('coords');
areas[i].setAttribute('data-original-coords', originalCoords);
}
newCoords = originalCoords.replace(/(\d+)/g,function(a){
return Math.round(a * multiplier);
});
areas[i].setAttribute('coords',newCoords);
}
}
}
function remapImage() {
var imgElement = document.getElementsByTagName('img')[0];
remap(imgElement);
}
// Add a window resize event listener
var addEvent = function(object, type, callback) {
if (object == null || typeof(object) == 'undefined') return;
if (object.addEventListener) {
object.addEventListener(type, callback, false);
} else if (object.attachEvent) {
object.attachEvent("on" + type, callback);
} else {
object["on"+type] = callback;
}
};
addEvent(window, "resize", remapImage);