загрузка шейп-файла со свойствами в не-UTF8 форматах - PullRequest
1 голос
/ 18 февраля 2020

Я могу успешно загрузить и отобразить шейп-файл в Leaflet. Однако, когда я пытаюсь получить доступ к свойствам объектов, все персонажи искажены. Для исследования я определил следующую функцию:

function unpack(str) {
    var codePoints = [];
    for(var i = 0; i < str.length; i++)
        codePoints.push( str.charCodeAt(i) );
    return codePoints;
};

Затем я делаю следующее:

const options = {
    onEachFeature: (feature, layer) => {
         console.log(unpack(feature.properties.NAME));
    }
};
L.shapefile(url, options);

При загрузке приложения я вижу в консольных массивах, как показано ниже:

[65533, 65533, 65533, 65533, 65533, 65533, 65533, 65533, 65533, 65533, 65533, 65533]

... что соответствует Символ замены Unicode .

Для чего он нужен, я проверил файл * .dbf с помощью бинарного редактора и установил, что feature.properties.NAME дан в ISO 8859-7 (ISO латинский / греческий алфавит).

1 Ответ

2 голосов
/ 18 февраля 2020

Давайте пройдемся по кроличьей норе того, как Leaflet.shapefile обрабатывает строки из свойств объектов.

Прежде всего, если вы немного знакомы с форматом шейп-файла , вы будете знакомы с тем фактом, что файл .shp содержит геометрию, а файл .dbf содержит свойства. Данные для каждой функции разделены между этими файлами.

Таким образом, Leaflet.shapefile зависит от shapefile js, чтобы выполнить синтаксический анализ, и, в свою очередь, shapefile js зависит от parseDBF для чтения содержимого файла .dbf. Чтение бита кода из parseDBF показывает, что есть поддержка нескольких кодировок символов с помощью iconv-lite :

module.exports = function(buffer, encoding) {
  var decoder = createDecoder(encoding);
  // ...etc...

Таким образом, можно вызвать parseDBF модуль с buffer для содержимого файла DBF и передачей строки с iconv-совместимой кодировкой.

Теперь, использует ли шейп-файл js эту функциональность? Еще раз давайте посмотрим на код :

  if (zip[name + '.dbf']) {
    dbf = parseDbf(zip[name + '.dbf'], zip[name + '.cpg']);
  }

Это означает, что "если есть файл .dbf, вызовите parseDBF с содержимым файла .dbf и содержимым файла .cpg ". Подождите, почему он читает файл .cpg? Что это обозначает? Ответ есть в любом списке файлов вспомогательных файлов шейп-файлов, таких как файл в википедии :

.cpg - используется для указания кодовой страницы (только для .dbf) для определение используемой кодировки символов

Это должно показать, что leaflet-shapefile обрабатывает кодировку символов, как и ожидалось - он считывает информацию о кодировке из правого бокового файла и декодирует строки из файла .dbf с помощью iconv-lite. Вы должны проверить, существует ли этот дополнительный файл и содержит ли содержимое этого файла нужную кодировку символов.

Обратите внимание, что список поддерживаемых кодировок для iconv-lite (а также поддерживаемые кодировки для iconv ) далеко не полны (по сравнению с списком известных текстовых кодировок ). Возможно, ваш .cpg файл в порядке, но поддержка этой кодировки текста просто отсутствует.

...