var ModelCache = {}; function createModelNode(Cesium,entity){ var model = entity.model; var modelNode; if(model){ var position = entity.position; var locationNode; if(position instanceof Cesium.SampledPositionProperty){ var data = position._property; var times = []; var values = data._values; var points = []; var len = data._times.length; var j = 0; var i = 0; while(j < len){ points.push(new Cesium.Cartesian3(values[i],values[i+1],values[i+2])); var time = data._times[j]; times[j] = Cesium.JulianDate.toIso8601(time); j++; i = i + 3; } var trackNodes = []; for(var i = 0,j = times.length;i < j;i++){ var coord = Cesium.Cartographic.fromCartesian(points[i]); var lon = Cesium.Math.toDegrees(coord.longitude); var lat = Cesium.Math.toDegrees(coord.latitude); var height = coord.height var coordStr = lon + ' ' + lat + ' ' + height; var coordNode = createNode('gx:coord',coordStr); var whenNode = createNode('when',times[i]); trackNodes.push(whenNode); trackNodes.push(coordNode); } var trackNode = addNodes('gx:Track',trackNodes); var altitudeModeNode = createNode('altitudeMode','absolute'); var interpolateNode = createNode('gx:interpolate','1'); var multiTrackNode = addNodes('gx:MultiTrack',[altitudeModeNode,interpolateNode,trackNode]); var styleUrlNode = createNode('styleUrl','#' + entity.id); var descriptionNode = createNode('description',''); var nameNode = createNode('name',''); locationNode = addNode('Location',multiTrackNode); } else{ var longitudeNode = createNode('longitude',0); var latitudeNode = createNode('latitude',0); var altitudeNode = createNode('altitude',0); locationNode = addNodes('Location',[longitudeNode,latitudeNode,altitudeNode]); } var docUri = new Cesium.Uri(document.location.href); var modelUri = new Cesium.Uri(model._uri._value); var baseUri = modelUri.resolve(docUri).toString(); var hrefNode = createNode('href',baseUri); var linkNode = addNode('Link',hrefNode); var xScaleNode = createNode('x',1); var yScaleNode = createNode('y',1); var zScaleNode = createNode('z',1); var scaleNode = addNodes('Scale',[xScaleNode,yScaleNode,zScaleNode]); var headingNode = createNode('heading',270); var tiltNode = createNode('tilt',0); var rollNode = createNode('roll',0); var orientationNode = addNodes('Orientation',[headingNode,tiltNode,rollNode]); var altitudeModeNode = createNode('altitudeMode','relativeToGround'); modelNode = addNodes('Model',[locationNode,orientationNode,scaleNode,linkNode]); } return modelNode; } function createStyleNode(entity){ var billboard = entity.billboard; var styleNode; if(billboard){ var img = billboard.image; var hrefNode; if(img){ var href = img._value; var hrefNode = createNode('href',href); var iconNode = addNode('Icon',hrefNode); var scaleNode; if(billboard.scale){ var scale = billboard.scale._value; scaleNode = createNode('scale',scale); } else{ scaleNode = createNode('scale',1); } var pixelOffset = billboard.pixelOffset; var hotSpotNode; if(pixelOffset){ var x = pixelOffset._value.x; x = -1*(x - billboard.width*0.5*scale); var y = pixelOffset._value.y; y = y + billboard.height*0.5*scale; var obj = { x : x, y : y, xunits : 'pixels', yunits : 'pixels' }; hotSpotNode = addOnlyAttrNode('hotSpot',obj); } var iconStyleNode = addNodes('IconStyle',[scaleNode,iconNode,hotSpotNode]) var path = entity.path; var lineStyleNode; if(path){ var color = path.material.color._value; color = 'ff0000ff'; var width = path.width._value; var colorNode = createNode('color',color); var widthNode = createNode('width',width); lineStyleNode = addNodes('LineStyle',[colorNode,widthNode]); } styleNode = addNodes('Style',[iconStyleNode,lineStyleNode],{ id : entity.id }); } } return styleNode; } function createPlaceMark(Cesium,entity,modelNode){ var position = entity.position; var placeMarkNode; var descriptionValue = ''; if(entity.description){ descriptionValue = entity.description.getValue(); } var description = ''.replace('{description}',descriptionValue); var entityName = ''.replace('{name}',entity.name); if(modelNode){ var nameNode = createNode('name',entityName); var descriptionNode = createNode('description',description); placeMarkNode = addNodes('Placemark',[nameNode,descriptionNode,modelNode]); } else{ if(position instanceof Cesium.CompositePositionProperty){ var intervals = position.intervals; if(intervals && intervals instanceof Cesium.TimeIntervalCollection){ var timeInterval = intervals._intervals[0]; if(timeInterval && timeInterval instanceof Cesium.TimeInterval){ var data = timeInterval.data._value._property; var times = []; var values = data._values; var points = []; var len = data._times.length; var j = 0; var i = 0; while(j < len){ points.push(new Cesium.Cartesian3(values[i],values[i+1],values[i+2])); var time = data._times[j]; times[j] = Cesium.JulianDate.toIso8601(time); j++; i = i + 3; } var trackNodes = []; for(var i = 0,j = times.length;i < j;i++){ var coord = Cesium.Cartographic.fromCartesian(points[i]); var lon = Cesium.Math.toDegrees(coord.longitude); var lat = Cesium.Math.toDegrees(coord.latitude); var height = coord.height var coordStr = lon + ' ' + lat + ' ' + height; var coordNode = createNode('gx:coord',coordStr); var whenNode = createNode('when',times[i]); trackNodes.push(whenNode); trackNodes.push(coordNode); } var trackNode = addNodes('gx:Track',trackNodes); var altitudeModeNode = createNode('altitudeMode','absolute'); var interpolateNode = createNode('gx:interpolate','1'); var multiTrackNode = addNodes('gx:MultiTrack',[altitudeModeNode,interpolateNode,trackNode]); var styleUrlNode = createNode('styleUrl','#' + entity.id); var descriptionNode = createNode('description',description); var nameNode = createNode('name',entityName); placeMarkNode = addNodes('Placemark',[nameNode,descriptionNode,styleUrlNode,multiTrackNode],{ id : entity.id }); } } } else if(position instanceof Cesium.SampledPositionProperty){ var data = position._property; var times = []; var values = data._values; var points = []; var len = data._times.length; var j = 0; var i = 0; while(j < len){ points.push(new Cesium.Cartesian3(values[i],values[i+1],values[i+2])); var time = data._times[j]; times[j] = Cesium.JulianDate.toIso8601(time); j++; i = i + 3; } var trackNodes = []; for(var i = 0,j = times.length;i < j;i++){ var coord = Cesium.Cartographic.fromCartesian(points[i]); var lon = Cesium.Math.toDegrees(coord.longitude); var lat = Cesium.Math.toDegrees(coord.latitude); var height = coord.height var coordStr = lon + ' ' + lat + ' ' + height; var coordNode = createNode('gx:coord',coordStr); var whenNode = createNode('when',times[i]); trackNodes.push(whenNode); trackNodes.push(coordNode); } var trackNode = addNodes('gx:Track',trackNodes); var altitudeModeNode = createNode('altitudeMode','absolute'); var interpolateNode = createNode('gx:interpolate','1'); var multiTrackNode = addNodes('gx:MultiTrack',[altitudeModeNode,interpolateNode,trackNode]); var styleUrlNode = createNode('styleUrl','#' + entity.id); var descriptionNode = createNode('description',description); var nameNode = createNode('name',entityName); placeMarkNode = addNodes('Placemark',[nameNode,descriptionNode,styleUrlNode,multiTrackNode],{ id : entity.id }); } else{ var point = position._value; var coord = Cesium.Cartographic.fromCartesian(point); var lon = Cesium.Math.toDegrees(coord.longitude); var lat = Cesium.Math.toDegrees(coord.latitude); var coordStr = lon + ',' + lat + ',' + coord.height; var coordNode = createNode('coordinates',coordStr); var pointNode = addNode('Point',coordNode); var nameNode = createNode('name',entityName); var descriptionNode = createNode('description',description); var styleUrlNode = createNode('styleUrl','#' + entity.id); var altitudeModeNode = createNode('altitudeMode','absolute'); placeMarkNode = addNodes('Placemark',[nameNode,descriptionNode,styleUrlNode,altitudeModeNode,pointNode]); } } return placeMarkNode; } function write(Cesium,entity){ var styleNode; var modelNode; var geometryNode;//暂时不支持 var placeMarkNode; if(entity.billboard){ styleNode = createStyleNode(entity); placeMarkNode = createPlaceMark(Cesium,entity,modelNode); } else if(entity.model){ modelNode = createModelNode(Cesium,entity); placeMarkNode = createPlaceMark(Cesium,entity,modelNode); } else{ } return { placeMarkNode : placeMarkNode, styleNode : styleNode }; } function createXML(content){ var head = ''; var nameSpace = ''; return [ head, nameSpace, content, '' ].join('\n'); } function writeKml(Cesium,entities){ //var dataSources = viewer.dataSources._dataSources; /*for(var i = 0,j = dataSources.length;i < j;i++){ var dataSource = dataSources[i]; var entities = dataSource.entities.values; for(var m = 0,n = entities.length;m < n;m++){ objs.push(write(entities[m])); } }*/ var objs = []; for(var m = 0,n = entities.length;m < n;m++){ objs.push(write(Cesium,entities[m])); } var openNode = createNode('open','1'); var visibilityNode = createNode('visibility','1'); var nameNode = createNode('name',''); var nodes = [openNode,visibilityNode,nameNode]; for(var i = 0,j = objs.length;i < j;i++){ var obj = objs[i]; nodes.push(obj['styleNode']); nodes.push(obj['placeMarkNode']); } var documentNode = addNodes('Document',nodes); var kmlNode = createXML(documentNode); return kmlNode; } function addOnlyAttrNode(nodeName,attr){ var startTag = '<' + nodeName; var result = [startTag]; for(var key in attr){ result.push(key + '=' + '\"' + attr[key] + '\"'); } result.push('/>'); return result.join(' '); } function createNode(name,content){ var startTag = '<' + name + '>'; var endTag = ''; return [ startTag, content, endTag ].join(''); } function addNodes(parent,children,attr){ var startTag = '<' + parent; for(var key in attr){ startTag += (' ' + key + '=' + '\"' + attr[key] + '\"' + ' '); } startTag += '>'; var endTag = ''; var result = []; result.push(startTag); for(var i = 0,j = children.length;i < j;i++){ var child = children[i]; if(child){ result.push(child); } } result.push(endTag); return result.join('\n'); } function addNode(parent,child){ var startTag = '<' + parent + '>'; var endTag = ''; return [ startTag, child, endTag ].join('\n'); } function saveKml(Cesium,viewer){ var entities = [].concat(viewer.entities.values); var dataSources = viewer.dataSources._dataSources; for(var i = 0,j = dataSources.length;i < j;i++){ var dataSource = dataSources[i]; var dataSourceEntities = dataSource.entities.values; for(var m = 0,n = dataSourceEntities.length;m < n;m++){ entities = entities.concat(dataSourceEntities[m]); } } var kmlContent = writeKml(Cesium,entities); var uri = 'data:text;charset=utf-8,' + encodeURIComponent(kmlContent); var downloadLink = document.createElement("a"); downloadLink.href = uri; var fileName = "myPlaceMarker" + "_" + new Date().toLocaleDateString() + ".kml"; downloadLink.download = fileName; document.body.appendChild(downloadLink); downloadLink.click(); document.body.removeChild(downloadLink); }