2013-02-19 81 views
2

我有一系列的(編碼或解碼)從谷歌地圖/開放街道地圖服務拍攝的折線。轉換折線到GeoJSON的

例如:

var polylines = ["kclaG|[email protected]@{[email protected]_AsCyCiBmBMMW[eCiC}A_BEEeBiB{@}@MW][email protected]@[email protected]][email protected][email protected]@[email protected]@[email protected]@{A}[email protected]{@{@[email protected]@[email protected]@[email protected]@QQY[[email protected]@AACCYY?AMKUUSSSQ]]GGECCCECA?AAA?A?C?G?WB" 
     ,"yfnaGld}[email protected]?]AuDAgA?KAkBGqG?{C?_B?S?aC?[?]A}A?wAASAQ" 
     ,"[email protected][email protected]"] 

我想將這些存儲爲GeoJSON的。我發現很多通過Leaflet等工具呈現GeoJSON的包,但是我很難找到可以將多段線導出到GeoJSON的包。

做任何像這樣的解決辦法是存在還是有,我應該尋找到這樣我就可以寫工具MYSET的GeoJSON的標準的特定子集?

附註:我最終要KML或SHP文件。我打算使用http://ogre.adc4gis.com/將GeoJSON轉換爲SHP。

+0

當你說「我有一系列捕獲的多義線」時,捕獲多義線的格式是什麼? – geocodezip 2013-02-19 21:50:50

+0

@geocodezip我在此刻JSON格式的編碼形式,雖然我已經加載,並通過單張渲染他們,讓我有機會獲得,使他們上了點。 – slifty 2013-02-19 21:58:41

+1

爲什麼你需要轉換爲GeoJSON?您可能會感興趣[這個工具](http://www.geocodezip.com/blitz-gmap-editor/test5.html),將您的編碼折線添加到地圖中,並將其導出爲KML。 – geocodezip 2013-02-19 22:07:38

回答

1

您正在尋找的GeoJSON的LineString的幾何類型。雖然算法有點複雜,但有一個a project on Github提供了JavaScript中的功能。您應該能夠輕鬆將其轉換爲您選擇的語言。我還將這些功能封裝到JSFiddle中,以便您可以將其用作在線工具。

您會在https://jsfiddle.net/ivansams/tw7qLvh4/2/找到該工具 - 您可以將編碼後的折線粘貼到「編碼折線」中,然後單擊「解碼」,這將返回一個GeoJSON LineString。下面的代碼是由於StackOverflow的規則要求JSFiddle伴隨有代碼,但是在Github項目站點上獲取最新的代碼。

function decode() { 
    var encodedPolyline = document.getElementById("encoded-polyline").value; 
    document.getElementById("geojson").value = encodedPolyline; 
    var coords = polyline.toGeoJSON(encodedPolyline); 
    document.getElementById("geojson").value = JSON.stringify(coords); 
} 

var polyline = {}; 

function encode(current, previous, factor) { 
    current = Math.round(current * factor); 
    previous = Math.round(previous * factor); 
    var coordinate = current - previous; 
    coordinate <<= 1; 
    if (current - previous < 0) { 
    coordinate = ~coordinate; 
    } 
    var output = ''; 
    while (coordinate >= 0x20) { 
    output += String.fromCharCode((0x20 | (coordinate & 0x1f)) + 63); 
    coordinate >>= 5; 
    } 
    output += String.fromCharCode(coordinate + 63); 
    return output; 
} 

/** 
* Decodes to a [latitude, longitude] coordinates array. 
* 
* This is adapted from the implementation in Project-OSRM. 
* 
* @param {String} str 
* @param {Number} precision 
* @returns {Array} 
* 
* @see https://github.com/Project-OSRM/osrm-frontend/blob/master/WebContent/routing/OSRM.RoutingGeometry.js 
*/ 
polyline.decode = function(str, precision) { 
    var index = 0, 
    lat = 0, 
    lng = 0, 
    coordinates = [], 
    shift = 0, 
    result = 0, 
    byte = null, 
    latitude_change, 
    longitude_change, 
    factor = Math.pow(10, precision || 5); 

    // Coordinates have variable length when encoded, so just keep 
    // track of whether we've hit the end of the string. In each 
    // loop iteration, a single coordinate is decoded. 
    while (index < str.length) { 

    // Reset shift, result, and byte 
    byte = null; 
    shift = 0; 
    result = 0; 

    do { 
     byte = str.charCodeAt(index++) - 63; 
     result |= (byte & 0x1f) << shift; 
     shift += 5; 
    } while (byte >= 0x20); 

    latitude_change = ((result & 1) ? ~(result >> 1) : (result >> 1)); 

    shift = result = 0; 

    do { 
     byte = str.charCodeAt(index++) - 63; 
     result |= (byte & 0x1f) << shift; 
     shift += 5; 
    } while (byte >= 0x20); 

    longitude_change = ((result & 1) ? ~(result >> 1) : (result >> 1)); 

    lat += latitude_change; 
    lng += longitude_change; 

    coordinates.push([lat/factor, lng/factor]); 
    } 

    return coordinates; 
}; 

/** 
* Encodes the given [latitude, longitude] coordinates array. 
* 
* @param {Array.<Array.<Number>>} coordinates 
* @param {Number} precision 
* @returns {String} 
*/ 
polyline.encode = function(coordinates, precision) { 
    if (!coordinates.length) { 
    return ''; 
    } 

    var factor = Math.pow(10, precision || 5), 
    output = encode(coordinates[0][0], 0, factor) + encode(coordinates[0][1], 0, factor); 

    for (var i = 1; i < coordinates.length; i++) { 
    var a = coordinates[i], 
     b = coordinates[i - 1]; 
    output += encode(a[0], b[0], factor); 
    output += encode(a[1], b[1], factor); 
    } 

    return output; 
}; 

function flipped(coords) { 
    var flipped = []; 
    for (var i = 0; i < coords.length; i++) { 
    flipped.push(coords[i].slice().reverse()); 
    } 
    return flipped; 
} 

/** 
* Encodes a GeoJSON LineString feature/geometry. 
* 
* @param {Object} geojson 
* @param {Number} precision 
* @returns {String} 
*/ 
polyline.fromGeoJSON = function(geojson, precision) { 
    if (geojson && geojson.type === 'Feature') { 
    geojson = geojson.geometry; 
    } 
    if (!geojson || geojson.type !== 'LineString') { 
    throw new Error('Input must be a GeoJSON LineString'); 
    } 
    return polyline.encode(flipped(geojson.coordinates), precision); 
}; 

/** 
* Decodes to a GeoJSON LineString geometry. 
* 
* @param {String} str 
* @param {Number} precision 
* @returns {Object} 
*/ 
polyline.toGeoJSON = function(str, precision) { 
    var coords = polyline.decode(str, precision); 
    return { 
    type: 'LineString', 
    coordinates: flipped(coords) 
    }; 
}; 

if (typeof module === 'object' && module.exports) { 
    module.exports = polyline; 
}