diff --git a/Makefile b/Makefile index a71d8c2..d105331 100644 --- a/Makefile +++ b/Makefile @@ -11,11 +11,10 @@ install: sh install.sh load: northeast_highway_intersects_building.csv tigerdelta-latest.zip osmi-latest.zip keepright-latest.zip - node index.js --fixed > fixed.json + node fixed.js rm -rf ldb mkdir ldb - sh load.sh fixed.json - rm fixed.json + sh load.sh stats: sh getStats.sh diff --git a/fixed.js b/fixed.js index f8c2b42..c331f5b 100644 --- a/fixed.js +++ b/fixed.js @@ -1,31 +1,50 @@ var fs = require('fs'), levelup = require('levelup'), leveldown = require('leveldown'), - key = require('./lib/key.js'); + queue = require('queue-async'), + key = require('./lib/key.js'), + rimraf = require('rimraf'); -var dbs = fs.readdirSync('./ldb/').filter(function(item) { - return item.indexOf('.ldb') > -1; -}); +function fixed(callback) { + var dbs = fs.readdirSync('./ldb/').filter(function(item) { + return item.indexOf('.ldb') > -1; + }); -if (!fs.existsSync('./fixed')) { - fs.mkdirSync('./fixed'); -} + if (!fs.existsSync('./fixed')) { + fs.mkdirSync('./fixed'); + } -dbs.forEach(function(ldb, idx) { - levelup('./ldb/' + ldb, { - createIfMissing: false, - max_open_files: 500 - }, function(err, db) { - if (err) return console.log(err); - var file = fs.createWriteStream('./fixed/' + ldb.split('.ldb')[0]); - file.once('open', function() { - db.createReadStream({lt: '0001'}) - .on('data', function(data) { - file.write(key.decompose(data.key).hash + '\n'); - }) - .on('end', function(data) { - file.end(); + var q = queue(); + + dbs.forEach(function(ldb, idx) { + q.defer(function(qcallback) { + levelup('./ldb/' + ldb, { + createIfMissing: false, + max_open_files: 500 + }, function(err, db) { + if (err) return console.log(err); + var filePath = './fixed/' + ldb.split('.ldb')[0]; + var file = fs.createWriteStream(filePath); + file.once('open', function() { + db.createReadStream({lt: '0001'}) + .on('data', function(data) { + file.write(key.decompose(data.key).hash + '\n'); + }) + .on('end', function(data) { + file.end(); + db.close(function(err) { + qcallback(err); + }); + }); }); + }); }); }); -}); + + q.awaitAll(function(err, results) { + if (callback) callback(err); + }); +} + +module.exports = fixed; +if (require.main === module) { fixed(); } diff --git a/import-csv.js b/import-csv.js index 835dc06..080a9fa 100644 --- a/import-csv.js +++ b/import-csv.js @@ -1,78 +1,121 @@ var fs = require('fs'), path = require('path'), - readline = require('readline'), csv = require('csv-parser'), levelup = require('levelup'), - key = require('./lib/key.js'); + key = require('./lib/key.js'), + queue = require('queue-async'), + rimraf = require('rimraf'); -if (process.stdin.isTTY) { +var verbose = false; +if (require.main === module) { + verbose = true; if (process.argv[2] === undefined) { return console.log('file argument required \n`node import-csv.js [source csv]`'); } - loadTask(process.argv[2]); -} else { - process.stdin.on('readable', function() { - var buf = process.stdin.read(); - if (buf === null) return; - buf.toString().split('\n').forEach(function(file) { - if (file.length) loadTask(file, process.argv[2]); - }); - }); + loadTask(process.argv[2], function() {}); } -function loadTask(fileLoc) { - var task = path.basename(fileLoc).split('.')[0], - db = levelup('./ldb/' + task + '.ldb'), - fixed_list = [], - count = 0; +module.exports = loadTask; - var tracking = levelup('./ldb/' + task + '-tracking.ldb'); - tracking.close(); +function loadTask(fileLoc, callback) { + var task = path.basename(fileLoc).split('.')[0], + topq = queue(); - if (fs.existsSync('./fixed') && fs.readdirSync('./fixed').indexOf(task) > -1) { - var rl = readline.createInterface({ - input: fs.createReadStream('./fixed/' + task), - output: new require('stream') + // ensure that we create & close the tracking database before loading anything + topq.defer(function(tqcallback) { + levelup('./ldb/' + task + '-tracking.ldb', {}, function(err, trackingdb) { + if (err) return tqcallback(err); + trackingdb.close(function(err) { + tqcallback(err); + }); }); + }); - rl.on('line', function(line) { - fixed_list.push(line); - }); + topq.awaitAll(function(err, results) { + // perform some tests to see if there's a 'fixed' file for this task + var fixedq = queue(); + fixedq + .defer(function(fqcallback) { + fs.readdir('./fixed', function(err, files) { + if (err) return fqcallback(err); + fqcallback(err, (files.indexOf(task) > -1)); + }); + }) + .defer(function(fqcallback) { + fs.stat('./fixed/' + task, function(err, info) { + if (err) return fqcallback(err); + fqcallback(err, (info.size > 0)); + }); + }); - rl.on('end', function() { - doImport(fileLoc); + // once the tests come back, check if they're all positive. if so, load fixes & tasks. + fixedq.awaitAll(function(err, results) { + if((!err) && results.every(function(x) { return x; })) { + fs.readFile('./fixed/' + task, function(err, data) { + var fixed_list = data.toString().split("\n"); + _doImport(fileLoc, task, fixed_list, callback); + }); + } else { + _doImport(fileLoc, task, [], callback); + } }); - } else { - doImport(fileLoc); - } + }); +} - function doImport(fileLoc) { - console.log('importing ' + task); - fs.createReadStream(fileLoc) - .pipe(csv()) - .on('data', function(data) { - var object_hash = key.hashObject(data); - if (fixed_list.indexOf(object_hash) === -1) { - // item is not fixed - var object_id = key.compose(1, object_hash); - db.put(object_id, JSON.stringify(data), function (err) { - if (err) console.log('-- error --', err); - }); - count++; - } - }) - .on('end', function() { - setTimeout(function() { - // insert a dummy object in unfixed keyspace if nothing has been inserted - // prevents blocking on levelup readstream creation against an empty db - if (count === 0) { +function _doImport(fileLoc, task, fixed_list, callback) { + if (verbose) console.log('importing task from ' + fileLoc); + var count = 0; + + levelup('./ldb/' + task + '.ldb', function(err, db) { + if (err) throw callback(err); + var q = queue(); + + q.defer(function(qcallback) { + fs.createReadStream(fileLoc) + .pipe(csv()) + .on('data', function(data) { + var object_hash = key.hashObject(data); + if (fixed_list.indexOf(object_hash) === -1) { + // item is not fixed + var object_id = key.compose(1, object_hash); + count++; + q.defer(function(qsubcallback) { + db.put(object_id, JSON.stringify(data), function(err) { + qsubcallback(err); + }); + }); + } + }) + .on('end', function(err) { + if(count === 0) { var keyval = key.compose(1, 'random'); - db.put(keyval, JSON.stringify({ignore: true})); + q.defer(function(qsubcallback) { + db.put(keyval, JSON.stringify({ignore: true}), function(err) { + qsubcallback(err); + }); + }); } - db.close(); - - console.log('done with ' + task + '. ' + count + ' items imported'); - }, 5000); + qcallback(err); + }); }); - } + + q.awaitAll(function(err, results) { + if (verbose) { console.log('done with ' + task + '. ' + count + ' items imported'); } + db.close(function(err) { + if (callback) callback(err); + }); + }); + }); +} + +/* +function deleteTask(task, callback){ + var q = queue(); + if (verbose) { console.log('deleting task ' + task); } + q.defer(rimraf, './ldb/' + task + '.ldb') + .defer(rimraf, './ldb/' + task + '-tracking.ldb') + .awaitAll(function(err, results) { + callback(err, results); + }); } +*/ diff --git a/install.sh b/install.sh index ab0ea75..7f6945d 100644 --- a/install.sh +++ b/install.sh @@ -4,7 +4,7 @@ if [ "$unamestr" = 'Darwin' ]; then brew install leveldb wget node elif [ "$unamestr" = 'Linux' ]; then apt-get -y update - apt-get install -y zip git vim htop bzip2 curl libleveldb-dev nodejs npm + apt-get install -y zip git vim htop bzip2 curl libleveldb-dev nodejs npm parallel sudo ln -s /usr/bin/nodejs /usr/bin/node apt-get install -y s3cmd ulimit -n 1000000 diff --git a/ldb/.gitignore b/ldb/.gitignore new file mode 100644 index 0000000..72e8ffc --- /dev/null +++ b/ldb/.gitignore @@ -0,0 +1 @@ +* diff --git a/lib/test-common.js b/lib/test-common.js new file mode 100644 index 0000000..c0971e6 --- /dev/null +++ b/lib/test-common.js @@ -0,0 +1,63 @@ +var levelup = require('levelup'), + key = require('./key.js'), + queue = require('queue-async'); + +function countTasksBySkipval(callback) { + levelup('./ldb/test.ldb', function(err, db) { + if (err) return callback(err); + var counts = {}; + db.createReadStream() + .on('data', function(data) { + var skipval = key.decompose(data.key).skipval; + if (!counts[skipval]) counts[skipval] = 0; + counts[skipval]++; + }) + .on('end', function() { + db.close(function(err) { + callback(err, counts); + }); + }); + }); +} + +function markTasksAsDone(tasks, callback) { + levelup('./ldb/test.ldb', function(err, db) { + if (err) throw callback(err); + var q = queue(); + tasks.forEach(function(task) { + q.defer(function(task, deferCallback) { + db.get(task, function(err, val) { + var k = key.decompose(task); + db.put(key.compose(0, k.hash), val, function() { + db.del(task, deferCallback); + }); + }); + }, task); + }); + q.awaitAll(function() { + db.close(function(err) { + callback(err); + }); + + }); + }); +} + +function blankslate(clearFixed, callback){ + var q = queue(); + if (clearFixed) { + q.defer(rimraf, './fixed/test'); + q.defer(rimraf, './fixed/test-tracking'); + } + q.defer(rimraf, './ldb/test.ldb'); + q.defer(rimraf, './ldb/test-tracking.ldb'); + q.awaitAll(function(err, results) { + callback(err); + }); +} + +module.exports = { + countTasksBySkipval: countTasksBySkipval, + markTasksAsDone: markTasksAsDone, + blankslate: blankslate +}; diff --git a/load.sh b/load.sh index 9c08315..4e80737 100644 --- a/load.sh +++ b/load.sh @@ -4,10 +4,10 @@ unzip -o keepright-latest.zip unzip -o osmi-latest.zip unzip -o tigerdelta-latest.zip -ls keepright-tasks/*.csv | node import-csv.js $1 -ls osmi-tasks/*.csv | node import-csv.js $1 -ls northeast_highway_intersects_building.csv | node import-csv.js $1 -ls tigerdelta-tasks/*.csv | node import-csv.js $1 +find osmi-tasks -type f | grep csv | parallel "node import-csv.js {}" +find keepright-tasks -type f | grep csv | parallel "node import-csv.js {}" +find tigerdelta-tasks -type f | grep csv | parallel "node import-csv.js {}" +node import-csv.js northeast_highway_intersects_building.csv rm -rf keepright-tasks rm -rf tigerdelta-tasks diff --git a/package.json b/package.json index 5d654b6..f413faf 100644 --- a/package.json +++ b/package.json @@ -13,10 +13,13 @@ "levelup": "^0.18.6", "mousetrap": "0.0.1", "osm-auth": "^0.2.6", + "queue-async": "^1.0.7", + "rimraf": "^2.2.8", "routes-router": "^3.1.0", "serve": "^1.4.0", "store": "~1.3.16", "stylus": "~0.47.3", + "tape": "^3.0.3", "watchify": "~1.0.1", "wellknown": "^0.3.0" }, @@ -31,7 +34,8 @@ "serve-stop": "./node_modules/.bin/forever stop index.js", "log": "./node_modules/.bin/forever logs index.js", "watch": "watchify js/index.js -o js/bundle.js", - "watch-css": "stylus -w css/site.styl" + "watch-css": "stylus -w css/site.styl", + "test": "tape test/*.js" }, "repository": { "type": "git", diff --git a/prioritize.js b/prioritize.js index 81b10b0..a0f550b 100644 --- a/prioritize.js +++ b/prioritize.js @@ -3,113 +3,166 @@ var fs = require('fs'), gju = require('geojson-utils'), key = require('./lib/key.js'), levelup = require('levelup'), - wellknown = require('wellknown'); + wellknown = require('wellknown'), + queue = require('queue-async'), + async = require('async'); -// adjusts skipvals based on geometry, prioritizing particular areas/markets +// adjusts task skipvals based on geometry, prioritizing particular areas/markets +var quickMode = true; +var verbose = false; +var maxOverlaps = 0; +var geojson = {}; -if (process.stdin.isTTY) { - var quickMode = true; // should we bother matching against every geometry or just quit after one hit? +if (require.main === module) { + verbose = true; + var quick = true; // should we bother matching against every geometry or just quit after one hit? + var geojsonFiles = []; - if (process.argv.length < 4) { - return console.log('file arguments are required\n`node prioritize.js [task] [geojson1 geojson2 ... ]`'); - } - - // process command line params, load geojson files - var geojson = {}; process.argv + .filter(function(elem, i) { return (i>2); }) .forEach(function(elem, i) { - if (i <= 2) { - // skip require params -- choosing not to use .filter() to make async logic simpler below - return true; - } - - // if using overlapping geojson files, this flag might be useful. otherwise, no. + // if using overlapping geojson files, this flag might be useful. + // otherwise, no. if (elem === '--slow') { - quickMode = false; + quick = false; } else { - var basename = path.basename(elem, '.geojson'); - - fs.readFile(elem, function(err, data) { - if (err) console.log('# Error loading GeoJSON file ' + elem); - var boundary = JSON.parse(data); - if ((boundary === null) || !boundary.features) { - console.log('# failed to load valid GeoJSON from ' + elem); - } else { - geojson[basename] = boundary; - console.log('- loaded GeoJSON file ' + elem); - } - - // if all params have been loaded, begin main processing - if(i === process.argv.length-1) ProcessLevelDB(); - }); + geojsonFiles.push(elem); } }); + + prioritize(process.argv[2], geojsonFiles, quick); } -function ProcessLevelDB(){ - console.log('- opening leveldb database ' + process.argv[2]); - levelup('./ldb/' + process.argv[2] + '.ldb', function(err, db) { - if (err) throw(err); +function prioritize(task, geojsonFiles, quick, callback) { + quickMode = quick; + var q = queue(); + geojsonFiles.forEach(function(f) { + q.defer(load, f); + }); + q.awaitAll(function(err, results) { + if (err) { + callback(err); + } else { + processGeoJSON(task, callback); + } + }); +} + +function load(elem, callback) { + fs.readFile(elem, function(err, data) { + if (err) { + if (verbose) console.log('# Error loading GeoJSON file ' + elem); + callback(err); + } + + var basename = path.basename(elem); + var boundary = JSON.parse(data); + if ((boundary === null) || !boundary.features) { + var err = 'no valid GeoJSON in ' + elem; + if (verbose) console.log('# ' + err); + callback(err); + } else { + geojson[basename] = boundary; + if (verbose) console.log('- loaded GeoJSON file ' + elem); + callback(null); + } + }); +} + +function processGeoJSON(task, callback) { + if (!callback) callback = function() {}; + if (verbose) console.log('- opening leveldb database ' + task); + + levelup('./ldb/' + task + '.ldb', function(err, db) { + if (err) return callback(err); + + var q = async.queue(function(data, qcallback) { + checkOverlaps(db, data, qcallback); + }); + + q.drain = function() { + reorder(db, maxOverlaps, function(err) { + db.close(function(err) { + callback(err); + }); + }); + }; - var maxOverlaps = 0; - console.log('- checking for geometry overlap'); + maxOverlaps = 0; + if (verbose) console.log('- checking for geometry overlap'); db.createReadStream() .on('data', function(data) { - data.value = JSON.parse(data.value); - - // if this task is already fixed, skip it - if (key.decompose(data.key).skipval === 0) return; - - // check if point is in any geojson geometries - var overlapCount = 0; - Object.keys(geojson).forEach(function(k) { - if (!data.value.st_astext) { - console.log('# missing geometry (st_astext) for key ' + data.key); - return false; - } - - if (gju.pointInPolygon(wellknown.parse(data.value.st_astext), geojson[k].features[0].geometry)) { - if (!data.value.priority) data.value.priority = []; - data.value.priority.push(k); - overlapCount++; - if (quickMode) return false; - } - }); + q.push(data); + }); + }); +} - // track maximum number of overlaps - maxOverlaps = Math.max(maxOverlaps, overlapCount); +function checkOverlaps(db, data, callback) { + data.value = JSON.parse(data.value); + + // if this task is already fixed, skip it + if (key.decompose(data.key).skipval === 0) return callback(null); + + // check if point is in any geojson geometries + var overlapCount = 0; + Object.keys(geojson).every(function(k) { + + // check for valid point geometry in the task object + if (!data.value.st_astext) { + if (verbose) console.log('# missing geometry (st_astext) for key ' + data.key); + return false; + } + + // test for presence of point in polygon + if (gju.pointInPolygon(wellknown.parse(data.value.st_astext), geojson[k].features[0].geometry)) { + if (!data.value.priority) data.value.priority = []; + data.value.priority.push(k); + overlapCount++; + if (quickMode) return false; + } + + return true; + }); - data.value.overlapCount = overlapCount; - db.put(data.key, JSON.stringify(data.value), function(err) { - if (err) console.log('# error saving key ' + data.key + '#' + overlapCount); + // track maximum number of overlaps + maxOverlaps = Math.max(maxOverlaps, overlapCount); + + // record findings in the task object record + data.value.overlapCount = overlapCount; + db.put(data.key, JSON.stringify(data.value), function(err) { + if (verbose && err) console.log('# error saving key ' + data.key + '#' + overlapCount); + callback(err); + }); +} + +function reorder(db, maxOverlaps, callback) { + // iterate through all keys, adding (maxOverlaps - overlap) to each skipval + if (verbose) console.log('- reordering tasks'); + var adjustmentsMade = 0; + var reordered = 0; + db.createReadStream() + .on('data', function(data) { + data.value = JSON.parse(data.value); + + // increment skipval based on number of overlaps + var keyComponents = key.decompose(data.key); + var newKey = key.compose((keyComponents.skipval + (maxOverlaps - parseInt(data.value.overlapCount))), keyComponents.hash); + if (parseInt(data.value.overlapCount) > 0) adjustmentsMade++; + + // rename the task ID to reflect the new skipval + delete data.value.overlapCount; + db.del(data.key, function(err) { + if (err && verbose) console.log('# error deleting key ' + newKey); + db.put(newKey, JSON.stringify(data.value), function(err) { + if (err && verbose) console.log('# error saving key ' + newKey); + reordered++; }); - }) - .on('end', function(){ - - // iterate through all keys, adding (maxOverlaps - overlap) to each skipval - console.log('- reordering tasks'); - var adjustmentsMade = 0; - - var reordered = 0; - db.createReadStream() - .on('data', function(data) { - data.value = JSON.parse(data.value); - var keyComponents = key.decompose(data.key); - var newKey = key.compose((keyComponents.skipval + (maxOverlaps - parseInt(data.value.overlapCount))), keyComponents.hash); - if (parseInt(data.value.overlapCount) > 0) adjustmentsMade++; - - delete data.value.overlapCount; - db.del(data.key, function(err){ - if (err) console.log('# error deleting key ' + newKey); - db.put(newKey, JSON.stringify(data.value), function(err) { - if (err) console.log('# error saving key ' + newKey); - reordered++; - }); - }); - }) - .on('end', function() { - console.log('- finished, reprioritized ' + adjustmentsMade + '/' + reordered + ' tasks'); - }); }); - }); + }) + .on('end', function() { + if (verbose) console.log('- finished, reprioritized ' + adjustmentsMade + '/' + reordered + ' tasks'); + callback(null); + }); } + +module.exports = prioritize; diff --git a/test/fixtures/africa.geojson b/test/fixtures/africa.geojson new file mode 100644 index 0000000..1597d58 --- /dev/null +++ b/test/fixtures/africa.geojson @@ -0,0 +1,120 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -10.8984375, + 35.31736632923788 + ], + [ + -2.28515625, + 36.5978891330702 + ], + [ + 2.8125, + 38.548165423046584 + ], + [ + 11.25, + 38.272688535980976 + ], + [ + 12.83203125, + 35.60371874069731 + ], + [ + 21.26953125, + 33.7243396617476 + ], + [ + 32.51953125, + 32.24997445586331 + ], + [ + 32.51953125, + 30.29701788337205 + ], + [ + 40.60546875, + 16.804541076383455 + ], + [ + 43.9453125, + 12.21118019150401 + ], + [ + 49.39453125, + 12.897489183755892 + ], + [ + 53.0859375, + 12.897489183755892 + ], + [ + 47.8125, + -2.986927393334863 + ], + [ + 60.8203125, + -20.13847031245114 + ], + [ + 57.83203125, + -25.79989118208832 + ], + [ + 46.93359375, + -28.30438068296277 + ], + [ + 36.9140625, + -25.95804467331783 + ], + [ + 28.828124999999996, + -35.7465122599185 + ], + [ + 18.28125, + -36.73888412439431 + ], + [ + 9.84375, + -22.593726063929296 + ], + [ + 8.7890625, + -10.833305983642491 + ], + [ + 5.625, + -0.8788717828324148 + ], + [ + -10.37109375, + 1.0546279422758869 + ], + [ + -21.26953125, + 14.093957177836236 + ], + [ + -18.28125, + 27.994401411046148 + ], + [ + -10.8984375, + 35.31736632923788 + ] + ] + ] + } + } + ] +} diff --git a/test/fixtures/north_america.geojson b/test/fixtures/north_america.geojson new file mode 100644 index 0000000..63b1a1d --- /dev/null +++ b/test/fixtures/north_america.geojson @@ -0,0 +1,92 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -182.109375, + 50.28933925329178 + ], + [ + -182.109375, + 55.57834467218206 + ], + [ + -171.2109375, + 56.75272287205736 + ], + [ + -173.671875, + 63.548552232036414 + ], + [ + -169.8046875, + 65.36683689226321 + ], + [ + -167.34375, + 70.1403642720717 + ], + [ + -158.55468749999997, + 73.22669969306126 + ], + [ + -112.5, + 80.11856387883782 + ], + [ + -78.75, + 79.03843742487174 + ], + [ + -56.25, + 64.16810689799152 + ], + [ + -45.703125, + 42.553080288955826 + ], + [ + -63.984375, + 15.961329081596647 + ], + [ + -80.15625, + 11.178401873711785 + ], + [ + -81.5625, + 5.266007882805511 + ], + [ + -113.90625, + 16.29905101458183 + ], + [ + -131.8359375, + 42.553080288955826 + ], + [ + -142.3828125, + 55.178867663281984 + ], + [ + -174.375, + 49.15296965617042 + ], + [ + -182.109375, + 50.28933925329178 + ] + ] + ] + } + } + ] +} diff --git a/test/fixtures/test.csv b/test/fixtures/test.csv new file mode 100644 index 0000000..bb9c2ac --- /dev/null +++ b/test/fixtures/test.csv @@ -0,0 +1,1001 @@ +way_id,node_id,st_astext +251672681,2578575122,POINT(6.183723 43.29946) +120878119,1435031684,POINT(-0.9658 37.896808) +224487565,2333090517,POINT(41.837388 48.350761) +262507992,2681789285,POINT(-1.622112 48.130562) +263561702,2691963312,POINT(-119.767201 39.390625) +151084020,1639255444,POINT(-0.169119 51.370436) +212393122,2222450326,POINT(14.128507 40.821305) +297297832,3011622922,POINT(18.900244 50.271035) +197462396,2077015784,POINT(12.427184 12.168936) +243644382,2510244807,POINT(7.775624 43.819096) +182623200,1929849733,POINT(-79.295286 43.726418) +250718138,2571062160,POINT(7.586164 51.9763) +50292117,639041951,POINT(8.593881 45.289358) +218131877,2274139882,POINT(-72.916109 41.309819) +297192289,3010433055,POINT(28.724242 40.977898) +232151023,2405224591,POINT(25.856479 60.668283) +42245376,526682648,POINT(18.413917 -33.933999) +151023631,1638722703,POINT(138.400553 34.938281) +228049606,2367002372,POINT(76.953912 43.293743) +172073837,1830173099,POINT(49.657494 58.594408) +270298447,2753428645,POINT(139.628903 35.907213) +264554699,2702211671,POINT(13.889655 40.749678) +298655189,3025469420,POINT(22.040118 49.64613) +254750649,2605614655,POINT(148.552001 -20.488733) +59384258,736479996,POINT(-1.434829 53.10165) +292020338,2955330831,POINT(19.033761 52.668262) +199392111,2093940748,POINT(8.795557 52.219547) +164248439,1758971023,POINT(-1.741076 38.479125) +293505229,2300184680,POINT(-11.370703 8.766706) +309722896,3150523921,POINT(22.08429 50.033985) +192651850,2031952830,POINT(7.221681 44.819686) +142184582,1556229497,POINT(11.489561 45.580478) +153992723,1666036672,POINT(7.582008 45.064263) +145071284,1585232900,POINT(27.57067 53.91037) +185061493,1956215859,POINT(137.016465 34.579452) +291237574,2946526287,POINT(-84.08295 41.033951) +99092993,1146454982,POINT(3.204195 39.564503) +272504278,2774203814,POINT(174.790017 -36.918201) +297131648,3009793903,POINT(-106.598876 52.185577) +305578699,3102218260,POINT(19.053784 50.258426) +152384180,1652041990,POINT(-2.989544 43.293878) +266132241,2717102953,POINT(-1.684482 48.10921) +92611651,1071941262,POINT(-21.742496 64.135796) +308762356,3140269639,POINT(4.357335 52.007076) +194775543,2904552149,POINT(-8.609395 41.151491) +225177974,2339857210,POINT(-75.610728 6.181434) +193799837,2043101561,POINT(-8.679348 41.784187) +146046833,1593433591,POINT(1.453982 49.102687) +216269671,2256219721,POINT(9.587765 40.291831) +192543659,2030955605,POINT(-68.582272 -31.532465) +284418956,2881670204,POINT(37.498739 55.822573) +295319527,2984005931,POINT(-73.490714 41.345835) +138322131,1516527906,POINT(24.257184 63.768159) +123161067,1374328533,POINT(132.306197 34.353659) +190072134,2006751157,POINT(135.373871 34.686865) +100846673,1165413533,POINT(-83.138181 31.867124) +239305001,2471035158,POINT(-3.786111 37.771186) +80331129,937545162,POINT(175.026642 -36.880175) +248360031,2551541580,POINT(17.106439 48.105129) +167288279,1786955684,POINT(39.056481 46.54324) +228725452,2373933260,POINT(14.479415 41.479829) +180389519,1908398664,POINT(-3.560906 41.721555) +306573790,3115357048,POINT(-8.85662 7.215828) +136355109,1495850051,POINT(5.744081 58.963755) +248322863,2551174031,POINT(-1.163654 52.955657) +172084842,1830255458,POINT(9.853758 50.469124) +208969927,2192235716,POINT(25.589499 60.380668) +107378224,1234174793,POINT(2.32848 48.875848) +64877414,795227594,POINT(13.027129 50.317451) +240127770,2478915939,POINT(11.583508 48.019936) +165082327,1766641187,POINT(8.557068 51.215156) +229826381,2383702696,POINT(-1.262665 51.770969) +202567396,2125331206,POINT(-16.273661 12.588411) +306477817,3114211309,POINT(151.37457 -33.279208) +175601966,1552128272,POINT(120.968264 24.903805) +120273563,1348986217,POINT(-117.922301 33.805942) +296139270,2999290579,POINT(116.496898 31.759143) +242166882,2496861273,POINT(65.399217 26.818761) +119451968,1342228152,POINT(15.785382 50.037751) +53797403,679121756,POINT(7.377449 51.533911) +233199561,2415560727,POINT(-112.029676 33.396142) +61744576,2055491555,POINT(59.66935 55.139874) +122850355,1946851178,POINT(6.142226 46.198723) +170405046,1815466375,POINT(129.855179 33.226055) +51408341,656285034,POINT(-3.070007 53.214667) +219645753,2287895222,POINT(139.729156 35.659754) +253662602,2595618614,POINT(-90.582613 41.501002) +22941474,247120110,POINT(-73.998056 40.765576) +261962352,2675918851,POINT(-93.453003 41.69025) +217960436,2272698121,POINT(-68.570625 -31.650888) +211737928,2217021910,POINT(9.200978 51.405578) +168003346,1793252704,POINT(-8.157764 43.10742) +303260834,3076096549,POINT(174.79278 -36.913929) +113577713,1287823280,POINT(136.407383 35.298429) +295260993,2989633658,POINT(-84.409882 39.131396) +112477929,1278333206,POINT(-63.458566 8.087964) +183272899,1703352029,POINT(80.1543 12.972867) +309740747,3150762295,POINT(-155.702849 20.027343) +11479324,102232449,POINT(-69.813773 44.884637) +294724149,2972146789,POINT(11.733235 50.41832) +181617871,1920292254,POINT(12.827629 41.82204) +52323257,665683403,POINT(-40.348594 -20.30585) +291465201,2949345587,POINT(19.10581 50.016298) +55263075,694394400,POINT(-105.093708 39.990568) +142237826,1556841047,POINT(105.946116 49.474226) +304599238,3091620157,POINT(11.66687 52.128438) +206123969,2161247318,POINT(17.903568 59.260765) +303475017,3078362378,POINT(27.618063 47.177362) +175142171,1857841808,POINT(13.130396 49.271173) +92631965,1072737638,POINT(-21.794655 64.112647) +103744581,1197753816,POINT(-21.951954 64.09081) +297148208,3009987769,POINT(8.684436 50.032761) +134106243,1474909505,POINT(-81.493004 28.450612) +169260666,1804267763,POINT(-2.087807 51.887206) +264345930,2700324502,POINT(55.773035 25.684147) +111489565,1970551935,POINT(2.222675 48.782494) +247207363,2541375954,POINT(149.219852 -35.385438) +304482957,3090259621,POINT(-104.749275 38.811211) +244944089,2522135695,POINT(-8.723391 41.23696) +192961813,2034943418,POINT(2.551296 41.591098) +223408890,2323078569,POINT(19.296968 50.244416) +121039629,1355684279,POINT(12.521385 41.871429) +159685074,1717940561,POINT(7.533885 47.598787) +310121895,3154855078,POINT(30.132745 8.313696) +219629428,2287733476,POINT(24.221002 56.935617) +205843055,2158261253,POINT(-0.867491 38.645081) +253847705,2597274616,POINT(10.258201 51.723369) +191011255,2015929768,POINT(-82.910301 40.497105) +239926803,2476955960,POINT(30.394056 59.717907) +249244381,2558818165,POINT(7.689666 48.487341) +138751266,1521510355,POINT(36.499951 54.122924) +237397229,2453046855,POINT(7.188474 51.169079) +300888052,3052030109,POINT(136.916191 35.176171) +306448842,3113558786,POINT(-71.897857 44.361665) +247977018,2548247182,POINT(134.613657 34.809324) +162181310,1741151059,POINT(115.996126 -31.892623) +283254938,2871449849,POINT(1.700984 41.212989) +230957351,2393804138,POINT(113.924631 22.529806) +68862823,827151064,POINT(61.39624 57.359673) +127586413,1411730714,POINT(20.409549 51.18251) +129080025,1424868808,POINT(174.776743 -36.912721) +113852556,1290780479,POINT(14.281628 48.274545) +111283682,1268257824,POINT(21.05571 52.131085) +264268588,2699607867,POINT(137.740602 34.777166) +110185750,1259149808,POINT(-8.471298 40.572519) +158867072,1710025460,POINT(135.790176 35.064125) +188447692,1990748202,POINT(2.037127 48.773626) +263324882,2689495023,POINT(3.330647 49.327938) +169320463,1804900436,POINT(138.393882 34.953746) +289623665,2931648845,POINT(34.040906 34.973533) +233923959,2422378572,POINT(-118.118488 34.14203) +216117827,2254833872,POINT(-77.233535 39.128765) +174418528,1296232103,POINT(6.65501 51.283067) +290087235,2936243852,POINT(-10.592999 8.299985) +169907414,1810663293,POINT(-21.088561 64.279739) +115502843,1304768547,POINT(118.261862 -22.308971) +296555729,3003494893,POINT(-86.153591 39.963629) +293480716,2970867096,POINT(22.599103 51.189157) +62251853,777410901,POINT(13.829139 45.657119) +48125566,611667513,POINT(24.888063 59.442188) +266160899,2717412764,POINT(-83.690566 42.207018) +304307266,3088363727,POINT(14.614632 40.740759) +216875650,2261986692,POINT(18.359128 49.678539) +151873873,1647121379,POINT(-1.990667 38.933235) +291581939,2950436607,POINT(143.868335 -37.564057) +232604273,2409489673,POINT(120.316774 22.639659) +198451225,2085777615,POINT(-75.697925 39.671329) +247333866,2542360139,POINT(10.091223 53.674274) +309636946,3149715604,POINT(37.48138 55.773413) +201870657,2118890323,POINT(9.086624 45.446601) +173161558,1839880792,POINT(70.025659 41.671145) +178493929,1888393403,POINT(121.49152 31.231831) +257805134,2632713493,POINT(-75.12356 39.827296) +308239807,3135296551,POINT(-77.055608 35.541435) +89919527,1042265409,POINT(18.693023 53.027612) +234302183,2425649601,POINT(2.294269 48.702373) +249670760,2562506350,POINT(139.74817 35.732806) +261831201,2674544357,POINT(9.43823 45.5426) +178692757,1890408250,POINT(25.173687 60.195897) +132855597,1461603537,POINT(-77.512344 -9.513712) +197839575,2080352488,POINT(-65.403323 -24.796132) +188413550,1990434020,POINT(6.258432 46.206941) +77252518,2047884363,POINT(-24.500962 14.893138) +150900173,1637652763,POINT(120.221396 23.072948) +288426168,2919862339,POINT(115.90442 29.613184) +224968048,2338072165,POINT(19.843846 45.254004) +228413371,2370953123,POINT(10.366613 59.371626) +179878606,1903120027,POINT(20.041836 49.990933) +112950437,1282536885,POINT(2.296035 49.126059) +285960621,2896017747,POINT(-95.803106 29.724406) +88172576,1024575488,POINT(-5.251608 36.375212) +92526588,1072737325,POINT(-21.797963 64.119039) +310228965,3156232286,POINT(7.091715 35.877792) +288248206,2918077280,POINT(139.766169 35.659081) +138184677,1514738299,POINT(-62.716308 8.278661) +52993717,671302005,POINT(1.312171 52.667934) +171521273,1825393248,POINT(129.847549 33.203516) +171230239,1822946493,POINT(44.777207 50.980421) +294997928,2986436231,POINT(29.232893 -29.75671) +297295099,3011567805,POINT(-6.010343 37.376489) +144338493,1578807503,POINT(-1.72205 51.03754) +123049263,1373378554,POINT(-76.521891 39.320786) +285269347,2889469119,POINT(13.930433 49.409161) +306338247,3112149329,POINT(142.163603 -38.063984) +252713291,2575577298,POINT(139.57095 35.562004) +214554927,2240763690,POINT(-95.733542 39.053693) +306469961,3114123611,POINT(133.307566 34.468469) +161974392,1739254013,POINT(-1.443102 54.901616) +298991826,3029179061,POINT(9.505125 45.303543) +287510685,2911148276,POINT(-0.834174 51.408788) +5013749,2639659281,POINT(21.007832 52.197428) +177576703,1879984632,POINT(6.290853 46.192643) +64454767,792696620,POINT(141.104265 42.407399) +219467508,2286178254,POINT(-8.543957 42.43317) +98689877,1141776730,POINT(37.598368 55.772032) +27328999,300010412,POINT(-2.69446 42.836103) +161934546,1737655729,POINT(-75.691053 4.792012) +183832330,2122259010,POINT(-0.961133 45.936488) +63816355,788545799,POINT(2.336506 48.840197) +310239579,3156337459,POINT(-11.101135 8.971638) +200170122,2101658688,POINT(139.356186 34.75342) +230064764,2385898936,POINT(151.014048 -33.725089) +168945227,1801255219,POINT(-56.013494 -15.518137) +71749601,853005157,POINT(27.423272 37.035768) +238218033,2460656169,POINT(-77.094878 -11.856108) +89241802,1070674976,POINT(39.885334 59.207145) +299531456,3035340779,POINT(11.272902 52.026908) +163474799,1751598366,POINT(-1.665973 42.806695) +208654351,2189305197,POINT(-147.346512 64.763988) +309383662,2508674981,POINT(44.059807 56.295149) +287648457,2912177901,POINT(-0.570921 51.314117) +180323898,1907553729,POINT(-3.789321 40.283145) +136309790,1495452868,POINT(16.869453 41.116634) +256699508,2623364751,POINT(17.106923 48.159251) +277856158,2823027941,POINT(-79.806324 43.249621) +127950110,1414911148,POINT(11.549618 45.54967) +156460287,2500073130,POINT(16.452361 38.476734) +308370392,3136575678,POINT(100.270956 13.502875) +170997813,1821022655,POINT(-79.443377 43.908904) +293120361,2966833046,POINT(0.567268 35.743691) +281037637,2850559721,POINT(2.074624 41.368341) +80163082,935195029,POINT(-0.4443 51.74037) +231158838,2395672994,POINT(175.18818 -41.340754) +297225548,3010841344,POINT(-5.088265 40.265459) +253083551,2590600274,POINT(6.881337 51.399927) +39853144,477807958,POINT(1.294379 52.638381) +74442846,879769325,POINT(-66.510302 46.206566) +311251317,3168442977,POINT(139.619599 35.384569) +233962146,2422718140,POINT(6.89726 52.216622) +162071169,1740165401,POINT(3.917889 43.628349) +130228038,904081811,POINT(-77.036034 -12.127077) +259901819,2653641004,POINT(121.533482 25.102824) +263672589,2693019986,POINT(11.976223 51.388512) +262351858,2680242286,POINT(5.374543 44.674938) +269124389,2744200416,POINT(81.82842 7.125997) +209973171,2201280475,POINT(72.999572 33.649283) +268161423,2735225944,POINT(-83.547688 12.671275) +262590290,2682474228,POINT(-94.430533 35.386991) +50717042,646256201,POINT(145.159115 -37.917639) +8982274,65777460,POINT(-149.923268 61.581406) +233277684,2416549138,POINT(10.699054 59.927794) +186017307,1967187790,POINT(139.617016 35.648856) +300180059,3042835999,POINT(-11.294561 8.004714) +241795889,2493859356,POINT(10.963023 45.965844) +294067384,847008187,POINT(-57.684584 -36.305528) +53763828,678837398,POINT(-79.62677 43.586403) +268462904,2738030419,POINT(11.034168 60.072034) +311878910,3176401506,POINT(9.574452 52.27198) +137138939,1504308527,POINT(10.835172 59.719889) +243030507,2504721714,POINT(15.161117 37.667279) +304114461,3086361787,POINT(45.810073 60.604604) +300993789,3051041276,POINT(13.532197 -12.447151) +104213083,1202444757,POINT(2.333108 48.861245) +257712891,2631884481,POINT(120.968429 14.2038) +223677586,2325465561,POINT(-122.96054 49.319716) +183624741,1940277744,POINT(37.489413 55.325159) +259603446,2620219173,POINT(14.964478 38.138971) +171480630,1825033600,POINT(174.645836 -36.853757) +92785348,1075988916,POINT(6.853357 47.63328) +230376890,2388869949,POINT(-74.43007 40.127308) +284292381,2880317012,POINT(9.664261 54.623519) +122549132,1369126264,POINT(6.060427 50.778204) +151792780,1839775742,POINT(-0.391785 53.009422) +244679017,2519714366,POINT(10.835062 44.531667) +236899960,2448592565,POINT(12.379336 51.249923) +311084145,3166294488,POINT(9.794673 50.97013) +234241080,2425157448,POINT(96.820349 4.564646) +102319588,1181143954,POINT(21.002074 52.313532) +275712163,2803773342,POINT(29.004549 41.230412) +254275992,2600653090,POINT(-78.945273 43.901315) +116539068,1313548325,POINT(1.876028 47.953917) +297929943,3018311475,POINT(17.597969 52.551278) +83731102,1098001712,POINT(37.458412 55.818143) +143011495,1564841975,POINT(94.59302 56.114807) +156738679,2627854221,POINT(2.180739 41.420511) +215453893,2249018898,POINT(-2.088858 52.779936) +238694549,2464982204,POINT(-104.577147 38.980398) +204616535,2146098439,POINT(121.516397 25.047085) +103309284,1193009764,POINT(-21.915872 64.091431) +244036941,2513892970,POINT(145.000735 -37.712736) +289524507,2930821049,POINT(21.899154 48.751184) +163099906,1748686458,POINT(-2.434351 55.607204) +102310541,1180970696,POINT(17.708189 59.863883) +310393592,3158128662,POINT(0.323409 50.793787) +121787583,1362381916,POINT(-97.300265 32.914013) +188929219,1995602652,POINT(6.871467 51.172701) +298479293,3024006221,POINT(2.482543 41.753924) +144074573,1576576411,POINT(11.538151 48.148559) +149213570,1622259487,POINT(10.941587 44.634578) +258679736,2640066568,POINT(19.57303 50.270815) +164862363,1764573684,POINT(-0.45763 39.465262) +245708289,2528519887,POINT(6.91017 50.954413) +128222147,1417459376,POINT(-120.359964 50.693313) +175115222,1616176230,POINT(-79.042911 44.294881) +74643648,881705480,POINT(-82.4368 27.958182) +199220369,2092402935,POINT(-4.091934 55.765379) +114446415,1296450606,POINT(18.323647 50.377075) +294234346,2977982835,POINT(-79.985955 37.226829) +253152619,2591273837,POINT(150.072481 -36.426652) +45731996,582505599,POINT(139.436837 35.532076) +270722526,2757246134,POINT(-6.673934 53.392989) +135084845,1483909971,POINT(36.130987 51.712577) +310407874,2627253830,POINT(22.441196 51.198199) +280218281,1369699616,POINT(34.915398 31.821705) +52555063,667679962,POINT(-40.313696 -20.303874) +220014575,2291373084,POINT(36.172078 51.788546) +129585472,1429432257,POINT(7.042894 49.264792) +160309404,2109054067,POINT(11.43276 48.74809) +282025510,2859746651,POINT(11.317212 50.971149) +232615446,2409581704,POINT(141.351323 43.069397) +193164368,2036817767,POINT(131.654073 33.224321) +251950226,2580908940,POINT(11.530744 48.093108) +102356127,1178015546,POINT(-111.478779 40.640988) +209739372,2199316042,POINT(114.175737 22.361794) +307637509,3128353841,POINT(-84.736724 33.730057) +211042598,2210509813,POINT(8.927211 44.407935) +271515376,2764797763,POINT(-108.307384 52.770287) +183173771,1935397700,POINT(11.854916 45.838141) +294216356,2977805700,POINT(14.688626 36.907633) +137754576,1510710053,POINT(-81.150371 42.988023) +224993744,2338251254,POINT(17.140734 48.194153) +298275804,3021844975,POINT(10.733839 45.50913) +217697608,2270081202,POINT(-1.33288 50.91447) +121012611,1355453074,POINT(9.701664 50.574862) +58696379,727332451,POINT(-4.370694 48.373817) +185201370,1957612071,POINT(1.837048 41.833918) +158895087,1710190376,POINT(139.581026 35.447369) +151368991,1641954996,POINT(-83.455329 41.736923) +224192918,2330168835,POINT(116.436957 40.24512) +198735645,2088370528,POINT(6.920679 47.478498) +212172340,2220585359,POINT(-105.820701 32.789613) +151969201,1648056328,POINT(145.147053 -37.998557) +151337550,1641601886,POINT(37.464421 55.804632) +116155784,1310530040,POINT(5.807314 45.217993) +289913076,2934462721,POINT(-17.426737 14.729045) +253009202,2590036712,POINT(8.430257 45.313581) +251903393,2580579510,POINT(1.607671 50.430987) +192763815,2033013786,POINT(115.965033 40.349367) +202359728,2123273856,POINT(-83.203832 42.317121) +201511427,2115084070,POINT(10.793845 59.778821) +89535358,1037999920,POINT(87.119003 53.755766) +167436763,1788321501,POINT(18.061602 53.113689) +176294134,1868412341,POINT(19.884347 51.367958) +185737981,1964023314,POINT(-58.390924 -34.609863) +243913534,2512687191,POINT(11.363975 48.129074) +186530620,1972625536,POINT(0.73069 51.337974) +292434319,2959901072,POINT(36.016365 52.949345) +244390247,2517158265,POINT(8.798737 45.659857) +268413993,2737510356,POINT(-79.511611 43.759102) +265828673,2714458208,POINT(5.330989 50.930951) +143197700,1566898912,POINT(8.805064 52.239639) +28439967,380237093,POINT(6.302137 50.820903) +142948450,1564114051,POINT(50.262814 53.27658) +171678791,1826724130,POINT(106.807251 -6.547068) +260275576,474660562,POINT(12.057488 50.249772) +106175986,1222308799,POINT(48.297789 54.272636) +163922969,1755857864,POINT(106.202937 11.810493) +37437707,437889558,POINT(27.679189 54.00818) +274911677,2795807090,POINT(16.945707 52.437504) +201248560,2112052429,POINT(21.989462 50.022311) +242622947,2500829928,POINT(6.644396 46.525402) +80340804,937615141,POINT(1.094944 49.444319) +101455097,1171446760,POINT(-75.439588 46.525782) +178487376,1888325987,POINT(-5.966434 54.06266) +65067363,796664511,POINT(144.770103 -37.864579) +237390954,2452978185,POINT(-53.71542 -29.705343) +288241507,2917972923,POINT(22.064482 53.167239) +170164107,1813183704,POINT(-3.502633 42.666771) +269712810,2748585933,POINT(2.515102 48.998293) +45031309,571098081,POINT(115.800023 -31.980677) +53657236,1137111994,POINT(-123.252617 49.257777) +299660547,3036936419,POINT(44.419867 54.029202) +291581239,2950431856,POINT(143.847099 -37.549172) +230832932,2392719558,POINT(25.600955 49.551386) +306150453,3109830968,POINT(6.830393 52.237532) +235041413,2431470714,POINT(17.926661 50.662267) +105534750,1215370447,POINT(2.299953 48.841428) +162734155,1745725392,POINT(11.20746 46.011173) +211715349,2213509613,POINT(-77.106027 38.847897) +243261921,2506818818,POINT(4.8038 44.136136) +166278107,1777365364,POINT(6.617345 51.34319) +254558186,2603568125,POINT(1.098131 52.110696) +265692750,1480735154,POINT(-117.918848 33.813358) +226720373,2354777551,POINT(-66.807743 10.13276) +94729534,502482230,POINT(-2.366143 51.781712) +302853197,3071341084,POINT(-10.029879 6.23733) +72192225,287712204,POINT(8.771639 51.70728) +301625417,3057046144,POINT(19.925051 50.018982) +178646023,1889965453,POINT(5.365261 43.300799) +255658614,2613299365,POINT(67.00624 39.696928) +82568395,960881481,POINT(2.068674 48.535374) +215383084,2247997280,POINT(1.431252 43.597711) +301206248,3053086899,POINT(-117.919374 33.810152) +190834683,2014418870,POINT(133.924214 34.187623) +308663218,3067676167,POINT(10.440953 53.248385) +60193816,747619481,POINT(-80.419933 37.232145) +215163836,2245805438,POINT(139.699707 35.537563) +230256181,2387789901,POINT(9.352907 46.16631) +246451807,2534943314,POINT(125.024353 10.05086) +238031230,2459007581,POINT(24.490806 57.651103) +48384563,614542825,POINT(-105.141777 40.19498) +225671113,2344273196,POINT(38.913891 57.291948) +283121129,2870351985,POINT(-3.216319 39.384168) +239116216,2469205664,POINT(9.34479 45.629546) +5290223,37475523,POINT(-76.692993 39.526421) +297770468,3016703698,POINT(-3.539576 40.420164) +113969324,1291618402,POINT(12.290257 45.981426) +189172593,257686386,POINT(-70.027715 -15.837901) +141108018,1544649288,POINT(-6.202771 36.529838) +190598214,2012431816,POINT(1.150997 49.018799) +306903882,3119273657,POINT(12.012638 42.864083) +155909868,1682555799,POINT(-71.184111 42.221013) +141597439,1549880891,POINT(-93.116368 44.952775) +206958455,2170585991,POINT(140.881518 38.640703) +188058308,1986837360,POINT(134.204739 34.877989) +304436647,3089699492,POINT(34.896223 32.078762) +291711292,2951866625,POINT(49.678826 58.606251) +80349249,937726174,POINT(-72.265813 18.553837) +255521981,2612036978,POINT(120.971674 24.86936) +185652980,2411090815,POINT(19.119993 50.321563) +300969294,3050776866,POINT(-62.296264 -38.70608) +238816387,2466153107,POINT(8.221815 48.838555) +255738040,2614214282,POINT(-2.917333 51.334034) +310180829,3155716228,POINT(-121.33644 38.795873) +233868652,2421920985,POINT(12.091213 45.133029) +165496301,1770366890,POINT(2.389623 48.843598) +248290480,2550938121,POINT(26.699926 54.916304) +304271900,3088042599,POINT(8.197797 48.902882) +170429242,1815703213,POINT(129.853752 33.220203) +274840297,2795095407,POINT(-77.534317 38.988546) +173398580,1842222551,POINT(28.082547 -26.060051) +217198802,2264915179,POINT(45.016693 53.212301) +26723565,293112411,POINT(3.820528 43.631472) +58430248,724387137,POINT(8.61563 51.120438) +116082492,1310014766,POINT(8.889948 48.620114) +164982556,1765744126,POINT(129.844097 33.222516) +302979396,3072708206,POINT(-74.801601 4.308932) +186902209,1976493199,POINT(23.590096 52.728842) +47360226,603040024,POINT(15.811861 50.046676) +140420877,1538501617,POINT(10.445473 53.229939) +163384365,1750906102,POINT(49.258232 53.499656) +259506047,2649376973,POINT(139.44901 35.487066) +215571721,2250364044,POINT(17.141068 48.156611) +275892181,2805519204,POINT(9.859876 53.558503) +218059064,2273603017,POINT(68.87667 36.723653) +124517826,1385827720,POINT(55.786536 52.764946) +129546676,1429092542,POINT(12.008698 45.805694) +38121239,448582416,POINT(18.091641 48.674213) +138997809,1523706688,POINT(3.975331 50.500039) +311334556,3169426066,POINT(9.348266 45.11341) +197776960,2079705977,POINT(13.782141 51.016425) +276373218,2809785791,POINT(-83.557467 41.640572) +291581935,2950437749,POINT(143.861793 -37.565569) +150234231,1631589224,POINT(2.376237 48.844283) +242362922,2498491439,POINT(-0.173775 53.168571) +231855743,2401831198,POINT(-66.330969 -33.289556) +35009620,331144344,POINT(21.01018 52.245391) +150655742,1833409367,POINT(-8.231006 37.108912) +299684792,3037270664,POINT(20.054375 50.097385) +124517813,1385827953,POINT(55.749702 52.764759) +224138020,2329698406,POINT(-84.139708 34.133127) +308474341,3137555229,POINT(-71.571593 43.204331) +269137581,2744294049,POINT(132.746519 33.826006) +223668645,2325389910,POINT(17.969585 50.671266) +171581925,1825891430,POINT(129.82972 33.204049) +116619738,1314275921,POINT(88.443179 26.68251) +217318421,2265918684,POINT(11.570765 49.948251) +249375729,2559855980,POINT(4.746562 52.385602) +245454626,2526487711,POINT(135.429411 34.728958) +200859775,2108117690,POINT(6.233667 46.212744) +260912020,2665108158,POINT(-13.955491 28.380253) +48954747,621142176,POINT(150.670677 -34.049247) +95208497,1104472758,POINT(-0.066012 52.215406) +255741642,2614277423,POINT(-76.614169 0.831573) +148829959,1618963718,POINT(-6.171077 36.531174) +283275069,2871627519,POINT(-60.182077 -35.439658) +209145510,2193798972,POINT(130.353688 33.653912) +198007525,2082004519,POINT(9.085986 45.440702) +264106845,2697750313,POINT(2.569407 48.629059) +194781697,2052855875,POINT(56.358122 25.084921) +72857279,864629316,POINT(-7.55234 42.995605) +224455045,2332768525,POINT(-84.145449 34.117282) +220718065,2298094611,POINT(14.213358 37.078768) +225299870,2340965279,POINT(-21.869075 64.112111) +113951097,1291463503,POINT(9.554936 45.184537) +243490322,2508867291,POINT(-0.138881 39.863346) +208259092,2185725474,POINT(13.752715 50.894301) +252113046,2582222089,POINT(13.075902 55.632808) +170425842,1815675485,POINT(129.853313 33.220696) +102943880,1188809686,POINT(17.650445 59.832181) +245403567,2526129196,POINT(135.429465 34.730461) +298389954,3023052198,POINT(-0.271135 39.957522) +106706232,1227324238,POINT(174.855921 -36.989415) +192914644,2034509394,POINT(0.380071 51.673632) +180067285,1905025470,POINT(-8.83429 37.201636) +31114388,345808760,POINT(27.593781 64.678315) +278457068,2828230566,POINT(139.514928 36.315394) +256980361,1646555228,POINT(140.042553 35.667995) +129896568,1432332026,POINT(-74.133543 4.878978) +233734037,2420741969,POINT(-5.782097 37.180579) +146915625,1601380767,POINT(84.97609 56.453348) +264277843,2699698557,POINT(11.875597 45.407117) +180245021,1880810096,POINT(17.935523 44.182034) +259923686,2653846771,POINT(55.513821 25.229873) +240861397,2485488556,POINT(-8.779243 41.533808) +150218607,1631495519,POINT(-6.134888 36.408621) +242943364,2503810041,POINT(-38.49373 -3.825877) +262437885,2681004285,POINT(-2.430881 53.424114) +290702374,2942097537,POINT(32.461892 2.749827) +195994864,2063677356,POINT(8.454448 39.068954) +190837721,2014464492,POINT(-7.511246 42.525875) +153535471,1662148541,POINT(-4.217441 55.842257) +204595469,2145907951,POINT(-0.419763 51.700051) +106467479,1224772669,POINT(-0.07244 52.214256) +187746989,1983786194,POINT(-0.785587 38.11172) +222132764,2311060051,POINT(-96.709032 40.806454) +124229611,1383259904,POINT(-81.318391 42.966258) +266790588,2723042598,POINT(49.555121 54.237033) +221442718,2515442564,POINT(-4.290889 47.793454) +257822902,2632851409,POINT(18.402383 47.743733) +274802179,2794729526,POINT(-3.658202 40.434969) +224286287,2331049486,POINT(10.866868 60.059392) +288222856,2917757171,POINT(37.584302 55.678542) +203618045,2136256836,POINT(7.179724 51.399642) +285357927,2890247103,POINT(2.362075 48.809733) +304658371,3092338585,POINT(12.52386 57.426719) +204413901,592111838,POINT(6.125268 45.49145) +107467960,1793626055,POINT(65.443632 62.141505) +291562095,2950255351,POINT(143.809263 -37.503241) +46703612,597058475,POINT(150.735265 -34.045922) +306213184,3110629579,POINT(42.827456 45.327874) +124428762,1387751105,POINT(2.867423 39.718426) +205342894,2153167552,POINT(17.009953 49.280387) +176262886,1868070250,POINT(-79.377953 43.642745) +256831984,2624623736,POINT(-81.153098 42.776302) +192053336,2026123872,POINT(4.406388 48.659721) +225933173,2347974065,POINT(121.502365 31.331439) +251763775,2579434915,POINT(8.427911 45.312215) +310900622,3164038860,POINT(153.023368 -27.553725) +6643556,47572811,POINT(4.743984 52.884678) +92550454,1071958898,POINT(-21.879322 64.124058) +260121881,2656069644,POINT(-44.304512 -22.418469) +43132798,540373241,POINT(7.021913 47.025962) +175896560,1864560397,POINT(16.908788 52.364413) +53569789,676746174,POINT(-1.302816 52.884463) +268402972,2737366120,POINT(10.26612 54.241315) +38267036,945388259,POINT(-119.864935 34.417466) +293445450,2970470600,POINT(-117.012929 33.944468) +291579016,2950419778,POINT(143.839903 -37.532693) +247040108,2539816324,POINT(-8.629425 40.62155) +165070106,1766512574,POINT(7.150783 50.730076) +291577485,2950406489,POINT(143.858949 -37.585045) +186137797,1968356762,POINT(18.760966 49.216062) +179064903,1894005038,POINT(-3.381943 51.534577) +62383041,2718961169,POINT(9.90383 53.631806) +256606266,2622558149,POINT(10.699207 50.632893) +194799292,2053070454,POINT(-92.096782 46.72989) +296687117,3004999965,POINT(3.788714 49.520118) +81659515,951643331,POINT(11.267507 50.687154) +309520660,3148704746,POINT(149.146383 -35.167554) +53306475,674336898,POINT(7.622056 51.542331) +198246899,502542178,POINT(-82.359064 28.064789) +197947723,2081423512,POINT(-3.714164 42.349914) +186575908,1973178863,POINT(5.823168 44.53503) +227113893,2358414849,POINT(12.614727 35.500361) +141775451,1551852128,POINT(-1.853205 38.998532) +273551559,2783891144,POINT(-117.542551 56.392949) +125804298,1396346529,POINT(8.709449 52.192736) +292144712,2956864327,POINT(124.245643 8.228809) +245329826,2525452686,POINT(17.06879 48.173837) +176332382,1868708437,POINT(1.332226 43.609744) +92515932,1071701460,POINT(-21.870814 64.131027) +86522568,292737537,POINT(24.920546 60.162026) +296888509,3006954955,POINT(12.280837 45.805471) +243627057,2510093901,POINT(32.016539 54.77646) +31838403,356390248,POINT(64.018433 67.529719) +102030740,3081177060,POINT(-0.070923 52.213231) +301694718,3057888233,POINT(-9.898424 6.177844) +103236242,1191944222,POINT(-0.068157 52.21252) +303353882,3077067372,POINT(14.684697 36.906578) +89825182,1041226370,POINT(1.24133 41.123326) +227983756,2366091575,POINT(-21.830449 64.087047) +198035207,2082246410,POINT(40.029887 45.039605) +292602561,2961352032,POINT(7.674335 48.821775) +226912016,2356368966,POINT(12.558499 48.023801) +279933516,2841105340,POINT(-113.987506 51.08846) +169462470,1806239222,POINT(-117.061323 33.132934) +153311912,1660234832,POINT(12.329462 43.308632) +199241441,2092580865,POINT(6.182078 43.299955) +199984219,2099647213,POINT(136.909432 35.134501) +142289769,1427340759,POINT(-81.213132 42.940148) +261461518,2670779782,POINT(-77.862516 40.801804) +277947092,2823844250,POINT(-73.144244 40.936329) +205769760,2157478073,POINT(4.216761 49.914027) +220292228,2294199336,POINT(32.74781 39.864672) +289394260,2929428652,POINT(-88.436264 14.847937) +200526644,1732289175,POINT(-1.086628 51.266982) +189137637,1997870511,POINT(-80.073826 40.510021) +86106401,999280305,POINT(106.014101 13.879638) +308822798,3095006743,POINT(-71.569635 43.206553) +43037128,539147478,POINT(2.136058 41.375768) +216636784,2260268645,POINT(9.033436 45.469397) +288033337,2915807564,POINT(7.842058 45.384694) +115678793,1306235092,POINT(11.27385 43.366215) +157093434,1693267064,POINT(11.421112 44.607413) +279075424,2833326240,POINT(22.063335 53.127108) +255865226,2615814475,POINT(-2.918756 51.33436) +25726195,280521050,POINT(-3.566293 50.434665) +87255504,1014568305,POINT(4.48656 51.223825) +117403151,27285344,POINT(6.018532 50.755417) +299676268,3037173174,POINT(-0.555707 38.19361) +250248814,2335635577,POINT(1.391195 43.63461) +296678559,3004877157,POINT(-2.113186 49.175423) +142987705,1564511588,POINT(-75.614667 39.723939) +200061931,2100495173,POINT(-1.783187 53.055617) +239841736,2476258070,POINT(7.253326 48.455154) +302711179,1523431538,POINT(11.006368 45.450198) +190875329,2014801414,POINT(69.0047 41.127773) +226040828,2348983915,POINT(43.490572 56.231548) +124732557,1387413205,POINT(25.095658 60.309708) +190839928,2014478707,POINT(6.258667 46.200469) +241001070,2486779862,POINT(60.93054 56.900517) +297831498,3017373107,POINT(139.578183 35.444836) +261406219,2670217107,POINT(3.062109 36.781053) +299638557,3036656601,POINT(8.470207 49.484817) +70936694,1048099816,POINT(10.899555 48.361624) +207156441,2173127831,POINT(44.108209 41.973195) +150166253,1630976544,POINT(-0.464472 51.362651) +309838050,3151769159,POINT(10.91504 48.391207) +189687320,2002798874,POINT(-68.587054 -31.506923) +285938071,2895776183,POINT(1.469788 48.452256) +41374069,506038917,POINT(-35.199029 -5.843203) +245650942,2528083484,POINT(-79.668093 37.142954) +289344966,2928975046,POINT(-6.275229 53.365423) +188028574,1986484863,POINT(133.937127 34.29765) +175662449,1862263138,POINT(-95.258949 38.92279) +237784398,2456584026,POINT(21.171193 52.416732) +45351842,576530389,POINT(-2.278074 51.188336) +97156573,1125413421,POINT(29.491005 -1.318922) +89762554,1040225602,POINT(-3.632036 37.203609) +181728384,1921582283,POINT(14.469172 41.481507) +84786677,984549294,POINT(-95.133505 29.506741) +94688658,3020458567,POINT(-87.913958 43.01868) +184281865,1947408547,POINT(-4.298854 48.608176) +220835426,2299172805,POINT(10.430622 53.232963) +270245676,2772223054,POINT(-74.239018 40.678306) +185326623,1959010970,POINT(-1.911816 53.25753) +229960003,2384994539,POINT(20.418724 52.203901) +297150863,3010017271,POINT(22.893972 42.42735) +219558378,2287041532,POINT(-116.151861 33.640679) +306223482,3110726532,POINT(138.8169 37.319163) +271934967,2768546894,POINT(-4.614028 36.737668) +259539094,2649672698,POINT(9.690252 52.395686) +227677834,2363242253,POINT(15.280073 49.96799) +199485599,2094735912,POINT(13.412708 52.52077) +254023942,2598599979,POINT(7.40042 51.388353) +291581855,2950436079,POINT(143.863926 -37.562775) +35447728,415797209,POINT(12.412901 51.312516) +138659323,1520400666,POINT(-2.345719 53.462787) +295323460,2990360423,POINT(120.598156 14.929766) +191056749,2016418708,POINT(131.65017 33.234739) +32839696,1349691871,POINT(30.398284 59.74515) +247271376,2541861520,POINT(2.822063 47.807144) +294163353,2977304596,POINT(-1.495541 46.424084) +201296230,2112533619,POINT(9.482865 51.198964) +196470264,2068012509,POINT(139.399359 35.318672) +244981334,2522469956,POINT(-1.328608 51.059681) +307012874,3120534040,POINT(31.101631 -29.623358) +169878926,2100683639,POINT(-117.062693 33.134661) +189094305,1997423553,POINT(-1.381256 52.861824) +205322854,2152983199,POINT(-8.349175 43.222081) +171054734,1821565241,POINT(129.842097 33.21493) +237368136,2452751354,POINT(139.72392 35.601951) +107544980,1235864136,POINT(19.050355 49.8197) +55352487,695273469,POINT(-79.597662 43.598734) +95697680,1109461907,POINT(-3.179614 51.462605) +71958253,855339261,POINT(13.444865 54.421702) +264858213,2705153641,POINT(-88.559984 40.022091) +263540857,2691713359,POINT(-81.657862 28.322163) +230286604,2388095816,POINT(-81.830981 30.194386) +260334608,2658067500,POINT(21.982677 50.020171) +172396215,1833029251,POINT(129.83362 33.176196) +85048268,986876781,POINT(5.866894 51.848581) +179846403,1902746672,POINT(-2.836782 53.969747) +132538074,1457810773,POINT(-1.543228 52.267971) +168910524,1800937831,POINT(15.086756 51.539072) +247639320,2545209809,POINT(135.704805 34.959708) +52494450,667221905,POINT(-40.318757 -20.269298) +304456592,3089908604,POINT(-75.430977 39.912101) +51178328,661523310,POINT(-2.725071 53.697391) +233588912,2419524837,POINT(-0.420264 38.373038) +118036326,1328452869,POINT(0.659032 51.603937) +224342904,2331631870,POINT(-84.135996 34.128037) +43224619,546404671,POINT(0.833392 51.883496) +46844030,598271971,POINT(-0.850446 41.67923) +219862501,2289956529,POINT(139.723366 35.727931) +202272208,2122460778,POINT(146.85708 -19.139014) +75609692,892671733,POINT(137.064315 50.583772) +291579062,2950421342,POINT(143.843191 -37.539948) +220379211,2295035696,POINT(14.420398 49.023178) +157457027,1696722585,POINT(172.724108 -43.601906) +142493387,1559416511,POINT(56.701705 52.867718) +179322133,1896669113,POINT(-45.272357 -20.898508) +204717326,2146993326,POINT(24.923676 60.169156) +154516860,1670446985,POINT(24.965021 64.71824) +239051209,2469361017,POINT(22.233171 50.091846) +269512435,2747169795,POINT(49.649985 58.597888) +25726199,496820110,POINT(-3.566554 50.43468) +291201627,2946172498,POINT(15.082073 37.517661) +221635995,2306684738,POINT(8.12882 44.234892) +284406248,2881541653,POINT(-66.897812 -19.470451) +216612752,2260056241,POINT(30.41243 60.57462) +136819899,1501094590,POINT(50.119507 53.187401) +157428238,2936927261,POINT(136.760618 35.275545) +284355605,2880977423,POINT(-74.823562 4.294686) +140088751,1534863336,POINT(8.484289 51.360426) +263191234,2688067039,POINT(116.109469 -8.573599) +25359610,276373066,POINT(-1.902721 43.314779) +165498577,1770389232,POINT(20.598507 49.812574) +234508255,2427515605,POINT(-81.677383 36.215696) +211393535,2213929695,POINT(140.985545 38.333236) +247133632,2540714373,POINT(-2.148216 34.344633) +25724858,280507065,POINT(-8.169768 43.407666) +280981403,3008389642,POINT(115.203537 -8.512255) +202717523,2106448975,POINT(28.787914 -2.595809) +291571219,2950345957,POINT(143.871355 -37.6082) +117826136,1326496214,POINT(-74.100022 4.554849) +86948638,1011543968,POINT(-1.082685 45.647418) +167373958,1787749156,POINT(-2.025475 52.495307) +226355090,2351972780,POINT(7.444458 46.932558) +105066875,1211117027,POINT(124.605763 11.010549) +204340048,2143419647,POINT(47.287278 50.800852) +99260954,1148164653,POINT(2.082992 48.067211) +270881830,2758442823,POINT(-1.772474 46.490581) +78191281,918436993,POINT(-4.642334 54.203744) +53284025,674182323,POINT(-40.318424 -20.290498) +263159104,2687924438,POINT(7.141294 51.211577) +233637394,2419903431,POINT(52.768524 58.122892) +114818057,1299730653,POINT(11.022728 50.975395) +306960956,3119828943,POINT(-79.228707 43.884434) +291580747,2950429346,POINT(143.816978 -37.558836) +283275062,2871627517,POINT(-60.173259 -35.43957) +49886098,633836821,POINT(-74.195241 4.632793) +237516023,2454058381,POINT(15.165368 37.636416) +187928355,1985638442,POINT(-7.59467 43.663312) +255812272,2615089295,POINT(-70.752054 -33.447596) +125095104,3155999677,POINT(15.577324 54.176763) +297132294,3009801085,POINT(120.348789 23.909063) +233436346,2418252749,POINT(44.390161 52.699713) +244390250,2517158264,POINT(8.79857 45.659965) +90848195,1054803060,POINT(10.42723 53.246614) +296948788,3007653676,POINT(22.003391 50.036285) +192322670,2028790449,POINT(-2.605241 55.580274) +237586918,2454663933,POINT(-68.939159 12.109734) +261620092,2672276411,POINT(-77.85855 40.796048) +236009683,2440840790,POINT(29.053884 40.967275) +180633825,1910752700,POINT(1.93701 49.162474) +123905381,1380313451,POINT(-0.189641 38.957294) +243069116,2492398301,POINT(21.07805 51.053983) +283102580,2870135160,POINT(48.511283 55.853299) +241107513,2488098500,POINT(-77.121707 38.887878) +125509102,1393837553,POINT(45.379561 2.081863) +198488512,2086187659,POINT(2.459596 49.18745) +175919358,1864777889,POINT(-97.539013 35.427817) +85653103,993749027,POINT(11.64689 48.143108) +148135823,1612383905,POINT(-1.566559 54.968196) +68237080,821821943,POINT(8.602128 46.347165) +232982068,2416098095,POINT(4.061384 48.311089) +302251828,3065009648,POINT(-2.951058 43.263976) +131648139,1969052734,POINT(10.339059 51.656876) +39139390,468419371,POINT(17.530364 48.454282) +263647679,2692737614,POINT(14.461649 50.121819) +155024360,1674694110,POINT(84.977426 56.448534) +300112089,3042108019,POINT(125.766067 39.010684) +294977803,2986163528,POINT(-84.460795 33.897159) +232074849,2404183175,POINT(25.588688 60.640838) +178001977,1883942334,POINT(20.042405 49.98769) +170746950,1818920529,POINT(-3.990897 50.544288) +307460475,3126180649,POINT(10.225174 45.64795) +308706502,3139714673,POINT(0.36773 46.646855) +286750157,2904200565,POINT(-6.436036 42.622779) +273526481,2783650509,POINT(-1.799765 53.587284) +23554391,255057083,POINT(10.457727 63.428105) +37590689,440657498,POINT(-2.802357 55.396761) +242942136,2503801272,POINT(10.835499 44.533101) +143415099,422508793,POINT(1.26894 38.96704) +293698864,2972894522,POINT(8.84457 53.03587) +281371217,2853289739,POINT(7.774476 48.564917) +114412197,1296096520,POINT(37.768434 55.426881) +304748157,3093440854,POINT(-4.07618 5.338339) +166159791,1776393145,POINT(-66.230568 47.445916) +140356109,1537827193,POINT(-79.70016 43.536533) +181222187,1916664219,POINT(37.577445 55.80949) +30437844,335903249,POINT(19.954213 52.105894) +254104427,2599282477,POINT(135.476126 34.749235) +159309183,1714114032,POINT(11.577557 43.443779) +286813972,2904894846,POINT(-119.695749 39.604368) +303429574,3077888511,POINT(10.541719 46.807015) +270088471,2751765348,POINT(-1.776985 46.492984) +111084509,1250664446,POINT(-117.919665 33.813871) +166378525,1778249071,POINT(28.192886 61.058394) +210898380,2209248142,POINT(-95.852625 39.097606) +196885052,2071723501,POINT(133.967085 34.856408) +268489207,2738247693,POINT(1.34873 49.169788) +311499936,3171699140,POINT(-97.086462 36.106728) +305757075,3104212519,POINT(-50.277245 -29.885884) +264397671,2700751547,POINT(-97.132554 36.11045) +197028787,2073153578,POINT(18.018997 49.533165) +171471179,1824936996,POINT(106.803432 -6.543852) +183249473,1849687512,POINT(16.188569 54.209381) +49438159,373281437,POINT(18.651054 50.289605) +285548685,2892098846,POINT(-15.430191 28.14517) +188413578,1990434065,POINT(6.25876 46.207019) +283188544,2870928487,POINT(-83.424845 42.345234) +129439424,1428127936,POINT(-81.20006 42.941452) +185579143,1962322639,POINT(116.003693 40.348545) +94365109,1985617163,POINT(17.385679 62.442571) +50340079,639590908,POINT(16.414244 41.153462) +58172403,721612291,POINT(-1.029978 45.621459) +113506536,1286786287,POINT(14.4547 50.124686) +171732723,1827180028,POINT(49.668929 58.59608) +212170501,2220575384,POINT(-74.554404 40.081576) +181822647,1922162317,POINT(37.606794 55.749411) +304990668,3095665152,POINT(9.168829 48.692239) +304547758,3090971369,POINT(6.978518 48.614275) +262116916,2677637364,POINT(-9.34038 38.797428) +52047215,663449134,POINT(-3.649949 42.345177) +305304986,3099120997,POINT(52.174718 58.665537) +61646371,768522547,POINT(7.852023 47.993801) +306175255,3110205483,POINT(11.028867 49.441689) +80923879,21181468,POINT(-4.085003 52.926008) +83210387,968237602,POINT(-72.17971 -13.271169) +237534661,2454234148,POINT(18.453404 53.493306) +310910049,2237410183,POINT(28.756107 60.710914) +198713282,2088144143,POINT(10.808708 44.541812) +124455482,1385298197,POINT(33.841183 27.096398) +88595516,1028809304,POINT(150.996813 -33.955563) +300836812,3049299483,POINT(-9.621929 6.120726) +165682012,1246854033,POINT(84.976192 56.477241) +309024799,3143315263,POINT(-77.8714 34.221573) +243068810,2505090468,POINT(-5.8764 43.35923) +301730491,3058229965,POINT(-9.82174 6.101221) +257626507,2631170869,POINT(11.566218 48.175228) +81397709,948421617,POINT(44.014581 56.195972) +269677000,2748355254,POINT(11.020743 50.574632) +143916958,1574755074,POINT(-17.198229 28.149278) +195215366,2258139732,POINT(8.630174 50.171413) +128105742,1416344870,POINT(25.14018 60.207283) +304022641,3085387852,POINT(-119.829275 39.536637) +232369743,2407224744,POINT(7.097574 51.608041) +213974745,2268638742,POINT(17.037033 51.080101) +28113915,308813890,POINT(-1.127271 51.265878) +230558548,2390517735,POINT(-74.860784 40.578099) +185979738,1966674101,POINT(-5.176332 39.9198) +224125249,2329538024,POINT(15.092069 37.58202) +130071436,1433724534,POINT(7.613514 50.350513) +230907766,2393400836,POINT(-121.927522 47.897914) +161534269,1735074422,POINT(-2.431132 55.591308) +264953582,2706025305,POINT(2.361128 41.515516) +263231818,2685858432,POINT(2.557882 44.32517) +176484297,1870024521,POINT(60.930219 57.099285) +154972515,1246559397,POINT(84.954256 56.466249) +220971973,2302814199,POINT(-2.98715 15.781591) +207328164,2175213674,POINT(6.966815 51.430997) +32229877,361433356,POINT(1.263563 52.63265) +274679995,2793640016,POINT(13.301357 42.517574) +211936054,2218615484,POINT(4.269794 52.106423) +177548253,1879696717,POINT(11.649709 48.252488) +268078639,2734391202,POINT(-1.00041 37.603092) +112493737,1278432537,POINT(9.323955 48.71586) +243122404,2505545391,POINT(24.044127 49.874634) +221296153,2303324132,POINT(-88.078446 30.249717) +308746604,3140106121,POINT(21.593046 53.076901) +129733591,1430679865,POINT(133.637994 33.567326) +299376995,3033585032,POINT(9.299735 46.040658) +225584237,2343479454,POINT(2.80992 50.380574) +308647303,3139166892,POINT(-73.860751 45.523834) +158849846,1709834437,POINT(26.481642 62.302008) +58198995,721764718,POINT(136.901979 35.126444) +291581641,2950435239,POINT(143.847594 -37.560875) +134992589,1483270218,POINT(-117.916517 33.812895) +307851643,3130842771,POINT(-87.416314 36.5765) +287145737,2907925556,POINT(-1.860674 51.186331) +95606800,1108626905,POINT(-68.011359 48.448188) +45750008,582685721,POINT(12.375383 50.795869) +205340198,2153139725,POINT(5.798589 46.143318) +54608661,687442164,POINT(5.093016 52.026668) +297826589,3017315362,POINT(34.384976 47.568521) +234595139,2428347216,POINT(-1.771801 43.340519) +32932554,370856011,POINT(-6.674947 53.400846) +104964174,1210210916,POINT(140.860902 38.265913) +42057904,2941837094,POINT(147.107506 -41.484606) +274965515,2796384469,POINT(-1.139937 46.152953) +293424707,2970235333,POINT(-1.973698 48.653931) +263968377,2696496581,POINT(30.424722 59.899967) +291573795,2950372965,POINT(143.806347 -37.579943) +237017609,2449673793,POINT(16.597823 49.195961) +160063094,1721309039,POINT(-60.019077 -34.895687) +225091315,2339152548,POINT(70.017172 41.521022) +16527092,170533365,POINT(-80.597025 35.847273) +176033249,1865935746,POINT(19.566499 50.264137) +164164014,1758218579,POINT(-2.013499 52.481538) +310149574,3155159400,POINT(17.018859 51.09382) +301258987,3067636852,POINT(10.524957 43.247952) +286249360,2898982939,POINT(24.989853 60.243003) +264588400,2702500385,POINT(-74.448968 24.100075) +280841085,2848780133,POINT(45.950677 51.573516) +215666531,2251374585,POINT(-71.570424 41.647503) +222149613,2311250485,POINT(10.780356 45.590522) +38608504,457315366,POINT(93.034022 56.000407) +165484650,1770236993,POINT(128.946533 35.174094) +304255798,3087892400,POINT(11.008296 46.650296) +220719044,2298107484,POINT(14.705271 40.8263) +171751878,1827325692,POINT(129.840372 33.197964) +30730838,339872114,POINT(-2.081292 52.595118) +198932057,2090024174,POINT(-9.099558 38.796384) +234204842,2424968558,POINT(-76.979863 38.971038) +239559702,2473372652,POINT(40.351004 43.383884) +197191843,2074758971,POINT(41.777771 42.67947) +266603825,2721351593,POINT(8.350433 59.832239) +257769052,2632394152,POINT(34.554789 49.417217) +92541827,1073654307,POINT(-21.887121 64.143128) +121035219,1355649581,POINT(-2.975785 51.336098) +111050190,1266063629,POINT(0.729628 51.339787) +229152319,2377820702,POINT(72.855512 19.044612) +277946413,2823842460,POINT(-73.114304 40.948359) +97858023,1132645558,POINT(-0.063967 52.219492) +284493893,2882322115,POINT(38.996061 45.146031) +230413394,2389205538,POINT(2.010862 41.559692) +4863279,2012567271,POINT(0.897125 51.139163) +298747423,3026677161,POINT(20.933826 52.374566) +28688495,312730212,POINT(9.700724 52.391281) +308152963,3134390812,POINT(-0.747645 53.399775) +167026413,1784277234,POINT(-73.094583 4.593816) +303962623,3084731919,POINT(-85.302268 35.082118) +245463495,2526549530,POINT(139.89164 35.6669) +239249705,2470525908,POINT(22.212253 50.065547) +300678225,3047850475,POINT(-9.880903 5.79728) +277440321,2819302633,POINT(30.252178 59.931421) +157598583,1698445795,POINT(28.362863 -15.302593) +206767229,2168077739,POINT(-76.544182 3.424101) +258944176,2642486219,POINT(-59.881818 -2.906975) +275918091,2805700084,POINT(153.182987 -27.928201) +309991861,3153504234,POINT(-2.192956 53.029734) +225736823,2344914530,POINT(19.104603 50.809599) +266647164,2721771485,POINT(-15.413661 28.154148) +264968699,2706180562,POINT(-114.700181 50.463757) +305897594,3105957352,POINT(28.454155 41.031195) +98542809,1139970062,POINT(-0.063721 52.214022) +47048517,600094371,POINT(11.282476 49.506706) +172251634,1831760022,POINT(10.163929 43.99757) +255627307,2613030965,POINT(-3.666065 40.417593) +295783400,2995426791,POINT(-71.138034 8.6257) +168141550,1794417608,POINT(21.259411 48.707426) +91275245,1059655778,POINT(82.895662 55.03444) +249730462,1342425286,POINT(-74.155699 4.563519) +311816914,3175550254,POINT(5.889375 49.638829) +228906565,2375611119,POINT(17.341861 50.482245) +236138993,2441978671,POINT(-67.520739 -46.432788) +131381579,1446036447,POINT(100.193456 16.758179) +217916312,2272232005,POINT(-78.685977 43.176895) +243286345,900662117,POINT(2.392944 51.048303) +226260096,2351169498,POINT(30.583903 50.487502) +297000982,3008400484,POINT(-99.14913 19.2421) +232835303,2411496632,POINT(18.303912 59.270083) +123250614,1375093045,POINT(2.128228 41.386986) +233923958,2422378497,POINT(-118.117772 34.14203) +203451372,3073473642,POINT(19.924473 50.046946) +208440486,2187325102,POINT(8.041301 52.27743) +306190737,3110364200,POINT(-106.086322 28.655313) +51846955,661357555,POINT(-40.30384 -20.300279) +230512568,2388961150,POINT(37.812452 55.65911) +297211295,3010644245,POINT(-3.727672 40.312507) +288813810,2923684536,POINT(56.001782 54.702841) +217842388,2265509781,POINT(10.824811 44.558955) +169163486,1803281013,POINT(1.880232 41.429858) +303944649,3084519388,POINT(7.386892 51.38974) +155067691,1675079360,POINT(12.522683 41.874728) +35449710,415817105,POINT(-122.372868 47.696431) +307316863,3124172227,POINT(13.123332 50.974649) diff --git a/test/test-import.js b/test/test-import.js new file mode 100644 index 0000000..1a5fcdb --- /dev/null +++ b/test/test-import.js @@ -0,0 +1,119 @@ +var tape = require('tape'), + levelup = require('levelup'); + importcsv = require('../import-csv.js'), + fixed = require('../fixed.js'), + queue = require('queue-async'), + rimraf = require('rimraf'), + common = require('../lib/test-common.js'); + +var doneTasks = [ + '0001-f5fb24d3845649bc670d8d4d6edadfca', + '0001-f6902ab0db17ab26bf5a78ca11365919', + '0001-f722cf3e5fa0f3925fc4b24d36faa304', + '0001-f754245da12019323c2b947296173f0a', + '0001-f7998822f3346c34bb3ee6ada58307ab', + '0001-f7b84c0ad5324c44b2a98e7d382d3334', + '0001-f854472855320d3d3c24797830423d38', + '0001-f8d0dc4d1424ade02530bd8ab084da67', + '0001-f8f3bdabf0aea2c92ba2954226bfe4fc', + '0001-f973d6f807b11cfd99a211b7dabb17ac', + '0001-f9acf7e4afbfe3ea1f40f8e1ec0c0721', + '0001-fa0667c241cb709b37d3e9d83adb2c4b', + '0001-faa2d1de31d022a43cf16f9cc763793b', + '0001-fabf656259e97997e83ede4154eabaa8', + '0001-fb143b4aaf980ae5e50248cb114ab2b7', + '0001-fb8af10e27274fd7548d9efb1e3b13c5', + '0001-fc22b3c01f3487e49af11fa129f08fb8', + '0001-fca5363cbdb074ab127c1f1759a1b380', + '0001-fcaa2d763c8a9983bfeab30280eb6d97', + '0001-fd518eca70733b65ad5df9383b945e42' +]; + +function blankslate(clearFixed, callback) { + var q = queue(); + if (clearFixed) { + q.defer(rimraf, './fixed/test'); + q.defer(rimraf, './fixed/test-tracking'); + } + q.defer(rimraf, './ldb/test.ldb'); + q.defer(rimraf, './ldb/test-tracking.ldb'); + q.awaitAll(function(err, results) { + callback(err); + }); +} + +tape('Basic import', function(t) { + t.plan(1); + var q = queue(1); + q.defer(blankslate, true) + .defer(importcsv, './test/fixtures/test.csv') + .defer(common.countTasksBySkipval) + .defer(blankslate, true) + .awaitAll(function(err, results) { + if (err) { + t.fail(err); + } else { + var count = results[2]; + var numTasks = 0; + Object.keys(count).forEach(function(k) { + numTasks += count[k]; + }); + t.equal(numTasks, 1000, 'Imported 1000 tasks'); + } + }); +}); + +tape('correct countTasksBySkipval() behavior', function(t) { + t.plan(2); + + var q = queue(1); + q.defer(blankslate, true) + .defer(importcsv, './test/fixtures/test.csv') + .defer(common.markTasksAsDone, doneTasks) + .defer(common.countTasksBySkipval) + .defer(blankslate, true) + .awaitAll(function(err, results) { + if (err) { + t.fail(err); + } else { + var count = results[3]; + t.equal(count['0'], 20, 'Found 20 completed tasks'); + t.equal(count['1'], 980, 'Found 980 incomplete tasks'); + } + }); +}); + +tape('importing fixed tasks', function(t) { + t.plan(2); + var q = queue(1); + + // load and mark tasks as done + q.defer(blankslate, true) + .defer(importcsv, './test/fixtures/test.csv') + .defer(common.markTasksAsDone, doneTasks) + + // record their fixed status + .defer(fixed) + + // delete all tasks but keep the fixed records + .defer(blankslate, false) + + // reload all tasks + .defer(importcsv, './test/fixtures/test.csv') + + // check that their fixed status was retained + .defer(common.countTasksBySkipval) + + // clean things up, including the fixed/test record + .defer(blankslate, true) + + .awaitAll(function(err, results) { + if(err) { + t.fail(err); + } else { + var count = results[6]; + t.equal(count['0'], undefined, '20 fixed tasks were not imported'); + t.equal(count['1'], 980, 'Found 980 incomplete tasks'); + } + }); +}); diff --git a/test/test-prioritize.js b/test/test-prioritize.js new file mode 100644 index 0000000..87a3b63 --- /dev/null +++ b/test/test-prioritize.js @@ -0,0 +1,27 @@ +var tape = require('tape'), + levelup = require('levelup'); + importcsv = require('../import-csv.js'), + fixed = require('../fixed.js'), + queue = require('queue-async'), + rimraf = require('rimraf'), + prioritize = require('../prioritize.js'), + common = require('../lib/test-common.js'); + +tape('Prioritization', function(t) { + t.plan(2); + var q = queue(1); + q.defer(common.blankslate, true) + .defer(importcsv, './test/fixtures/test.csv') + .defer(prioritize, 'test', ['./test/fixtures/africa.geojson', './test/fixtures/north_america.geojson'], true) + .defer(common.countTasksBySkipval) + .defer(common.blankslate, true) + .awaitAll(function(err, results) { + if (err) { + t.fail(err); + } else { + var count = results[3]; + t.equal(count['1'], 175, 'Prioritized 175 tasks'); + t.equal(count['2'], 825, 'Did not prioritize 825 tasks'); + } + }); +});