diff --git a/.gitignore b/.gitignore index 73a92f7460..5fb73328f2 100755 --- a/.gitignore +++ b/.gitignore @@ -69,7 +69,6 @@ lib *.sw* *.un~ -demos/mapbox.html demos/gd.html demos/data demos/image diff --git a/demos/01_point_circle.html b/demos/01_point_circle.html index bb80671de8..7121179c29 100644 --- a/demos/01_point_circle.html +++ b/demos/01_point_circle.html @@ -10,6 +10,9 @@ point_circle @@ -55,15 +58,15 @@ scene.on('loaded', () => { .shape('2d:circle') .size('value', [ 2, 80]) // default 1 //.size('value', [ 10, 300]) // default 1 - .active(false) + .active(true) .filter('value', field_8 => { return field_8 * 1 > 500; }) - .color('type', colorObj.red) + .color('type', colorObj.blue) .style({ stroke: 'rgb(255,255,255)', strokeWidth: 1, - opacity: 0.9 + opacity: 1. }) .render(); diff --git a/demos/01_point_column.html b/demos/01_point_column.html index 8e1abda83c..fd7d33ae02 100644 --- a/demos/01_point_column.html +++ b/demos/01_point_column.html @@ -34,9 +34,11 @@ scene.on('loaded', () => { zIndex: 2 }) .source(data.list, { - type: 'array', - x: 'j', - y: 'w', + parser:{ + type: 'json', + x: 'j', + y: 'w', + } }) .shape('cylinder') .size('t',(level)=> { diff --git a/demos/01_point_distribute.html b/demos/01_point_distribute.html index 18a714ab75..a3d1bd8f73 100644 --- a/demos/01_point_distribute.html +++ b/demos/01_point_distribute.html @@ -34,9 +34,11 @@ scene.on('loaded', () => { zIndex: 2 }) .source(data, { - type: 'csv', - y: 'lat', - x: 'lng' + parser:{ + type: 'csv', + y: 'lat', + x: 'lng' + } }) .size(1.0) .color('#0D408C') diff --git a/demos/02_point_circle.html b/demos/02_point_circle.html new file mode 100644 index 0000000000..cc95ad57d6 --- /dev/null +++ b/demos/02_point_circle.html @@ -0,0 +1,77 @@ + + + + + + + + + + point_circle + + + + +
+ + + + + + + + diff --git a/demos/04_image.html b/demos/04_image.html index 3f0773c96e..5acb717137 100644 --- a/demos/04_image.html +++ b/demos/04_image.html @@ -33,8 +33,11 @@ const scene = new L7.Scene({ scene.on('loaded', () => { const imageLayer = scene.ImageLayer(). source('https://gw.alipayobjects.com/zos/rmsportal/FnHFeFklTzKDdUESRNDv.jpg',{ - - extent: [ 121.1680, 30.2828, 121.3840, 30.4219 ] + parser:{ + type:'image', + extent: [ 121.1680, 30.2828, 121.3840, 30.4219 ] + } + }) .style({ opacity:1.0, diff --git a/demos/05_raster_dem.html b/demos/05_raster_dem.html index 0589eed6b4..fb560be45b 100644 --- a/demos/05_raster_dem.html +++ b/demos/05_raster_dem.html @@ -48,13 +48,14 @@ scene.on('loaded', () => { const layer = scene.RasterLayer({ zIndex: 2 }). source(values, { - type: 'raster', - width: n, - height: m, - min: 0, - max: 8000, - extent: [ 73.482190241, 3.82501784112, 135.106618732, 57.6300459963 ] - + parser: { + type: 'raster', + width: n, + height: m, + min: 0, + max: 8000, + extent: [ 73.482190241, 3.82501784112, 135.106618732, 57.6300459963 ] + } }) .style({ rampColors: { diff --git a/demos/grid.html b/demos/grid.html new file mode 100644 index 0000000000..94c2000bb9 --- /dev/null +++ b/demos/grid.html @@ -0,0 +1,74 @@ + + + + + + + + + point_circle + + + + +
+ + + + + + + + diff --git a/demos/mapbox.html b/demos/mapbox.html new file mode 100644 index 0000000000..661b3c33c3 --- /dev/null +++ b/demos/mapbox.html @@ -0,0 +1,93 @@ + + + + + + + + + + point_circle + + + + +
+ + + + + + + + + diff --git a/package.json b/package.json index 8ab26df3c2..01f457cb7e 100755 --- a/package.json +++ b/package.json @@ -101,12 +101,14 @@ "@turf/invariant": "^6.1.2", "@turf/meta": "^6.0.2", "d3-dsv": "^1.0.10", + "d3-hexbin": "^0.2.2", "earcut": "^2.1.3", "fecha": "^2.3.3", "gl-matrix": "^2.4.1", "lodash": "^4.17.5", "polyline-normals": "^2.0.2", "rbush": "^2.0.2", + "simple-statistics": "^7.0.1", "three": "^0.96.0", "venn.js": "^0.2.20", "viewport-mercator-project": "^5.2.0", diff --git a/src/core/controller/geom.js b/src/core/controller/geom.js deleted file mode 100644 index b0d474ac01..0000000000 --- a/src/core/controller/geom.js +++ /dev/null @@ -1,36 +0,0 @@ -import geom from '../../geom/geom'; -import { GeoBuffer, bufferGeometry, Material } from '../../geom/index'; - - -// geom shape buffer geometry material -// shape name type() -// buffer 1:n geometry -// geometry -// -export default function polygonGeom(shape, coordinates, properties, layerid) { - const polygongeom = geom.polygon; - const { buffer, geometry, material } = polygongeom[shape];// polygon 映射表 - const bufferData = new GeoBuffer[buffer]({ - coordinates, - properties, - shape - }); - bufferData.bufferStruct.name = layerid; - const bg = new bufferGeometry[geometry](bufferData.bufferStruct); - const mtl = Material[material](); - return { - geometry: bg, - mtl - }; -} - -export function pointGeom(shape, bufferData) { - const pointgeom = geom.point; - const { geometry, material } = pointgeom[shape]; - const bg = new bufferGeometry[geometry](bufferData.bufferStruct); - const mtl = Material[material](); - return { - geometry: bg, - mtl - }; -} diff --git a/src/core/controller/map.js b/src/core/controller/map.js new file mode 100644 index 0000000000..3068e61cfe --- /dev/null +++ b/src/core/controller/map.js @@ -0,0 +1,24 @@ + +import { getMap } from '../../map'; +import Base from '../base'; +export default class MapContorller extends Base { + constructor(cfg, engine, scene) { + super(cfg); + this._engine = engine; + this.scene = scene; + } + _init() { + const mapType = this.get('mapType'); + const mapCfg = this.get('mapCfg'); + this.map = new getMap(mapType)(mapCfg); + this.map('mapLoad', this._mapload.bind(this)); + } + _mapload() { + this.map.asyncCamera(this._engine); + this.emit('loaded'); + } + _bindMapMethod() { + + } + +} diff --git a/src/core/engine/index.js b/src/core/engine/index.js index d3a8eee42b..a12f2e06f6 100644 --- a/src/core/engine/index.js +++ b/src/core/engine/index.js @@ -11,6 +11,9 @@ export default class Engine extends EventEmitter { this._camera = new Camera(container).camera; this._renderer = new Renderer(container).renderer; this._world = world; + // for MapBox + this.world = new THREE.Group(); + this._scene.add(this.world); this._picking = Picking(this._world, this._renderer, this._camera, this._scene); this.clock = new THREE.Clock(); } diff --git a/src/core/engine/picking/picking.js b/src/core/engine/picking/picking.js index 0dfd718fbe..c467af20ce 100755 --- a/src/core/engine/picking/picking.js +++ b/src/core/engine/picking/picking.js @@ -11,6 +11,8 @@ class Picking { this.scene = scene; this._raycaster.linePrecision = 10; this._pickingScene = PickingScene; + this.world = new THREE.Group(); + this._pickingScene.add(this.world); const size = this._renderer.getSize(); this._width = size.width; this._height = size.height; @@ -34,8 +36,7 @@ class Picking { window.addEventListener('resize', this._resizeHandler, false); } pickdata(event) { - const point = { x: event.pixel.x, y: event.pixel.y, type: event.type }; - + const point = { x: event.offsetX, y: event.offsetY, type: event.type }; const normalisedPoint = { x: 0, y: 0 }; normalisedPoint.x = (point.x / this._width) * 2 - 1; normalisedPoint.y = -(point.y / this._height) * 2 + 1; @@ -61,12 +62,12 @@ class Picking { } _filterObject(id) { - this._pickingScene.children.forEach((object, index) => { + this.world.children.forEach((object, index) => { index === id ? object.visible = true : object.visible = false; }); } _pickAllObject(point, normalisedPoint) { - this._pickingScene.children.forEach((object, index) => { + this.world.children.forEach((object, index) => { this._filterObject(index); const item = this._pick(point, normalisedPoint, object.name); item.type = point.type; @@ -86,7 +87,6 @@ class Picking { id = -999; // return; } - this._raycaster.setFromCamera(normalisedPoint, this._camera); const intersects = this._raycaster.intersectObjects(this._pickingScene.children, true); @@ -111,13 +111,14 @@ class Picking { // // Picking ID should already be added as an attribute add(mesh) { - this._pickingScene.add(mesh); + this.world.add(mesh); + this._needUpdate = true; } // Remove mesh from picking scene remove(mesh) { - this._pickingScene.remove(mesh); + this.world.remove(mesh); this._needUpdate = true; } diff --git a/src/core/layer.js b/src/core/layer.js index 50f2858587..dc0afbd99e 100644 --- a/src/core/layer.js +++ b/src/core/layer.js @@ -5,7 +5,7 @@ import Base from './base'; import * as THREE from './three'; import ColorUtil from '../attr/color-util'; -import * as source from '../source/index'; +import source from './source'; import PickingMaterial from '../core/engine/picking/pickingMaterial'; import Attr from '../attr/index'; import Util from '../util'; @@ -63,7 +63,8 @@ export default class Layer extends Base { const layerId = this._getUniqueId(); this.layerId = layerId; this._activeIds = null; - scene._engine._scene.add(this._object3D); + const world = scene._engine.world; + world.add(this._object3D); this.layerMesh = null; this.layerLineMesh = null; this._initEvents(); @@ -106,12 +107,9 @@ export default class Layer extends Base { this._object3D.visible = this.get('visible'); } source(data, cfg = {}) { - const dataType = this._getDataType(data); - const { type = dataType } = cfg; cfg.data = data; - cfg.mapType = this.get('mapType'); - - this.layerSource = new source[type](cfg); + cfg.mapType = this.scene.mapType; + this.layerSource = new source(cfg); // this.scene.workerPool.runTask({ // command: 'geojson', // data: cfg @@ -279,10 +277,10 @@ export default class Layer extends Base { const { featureId } = e; if (featureId < 0) return; const activeStyle = this.get('activedOptions'); - const selectFeatureIds = this.layerSource.getSelectFeatureId(featureId); + // const selectFeatureIds = this.layerSource.getSelectFeatureId(featureId); // 如果数据不显示状态则不进行高亮 - if (this.StyleData[selectFeatureIds[0]].hasOwnProperty('filter') && this.StyleData[selectFeatureIds[0]].filter === false) { return; } - const style = Util.assign({}, this.StyleData[featureId]); + if (this.layerData[featureId].hasOwnProperty('filter') && this.layerData[featureId].filter === false) { return; } + const style = Util.assign({}, this.layerData[featureId]); style.color = ColorUtil.toRGB(activeStyle.fill).map(e => e / 255); this.updateStyle([ featureId ], style); } @@ -321,7 +319,7 @@ export default class Layer extends Base { _updateSize(zoom) { const sizeOption = this.get('attrOptions').size; const fields = parseFields(sizeOption.field); - const data = this.layerSource.propertiesData; + const data = this.layerSource.data.dataArray; if (!this.zoomSizeCache) this.zoomSizeCache = {}; if (!this.zoomSizeCache[zoom]) { this.zoomSizeCache[zoom] = []; @@ -339,7 +337,8 @@ export default class Layer extends Base { const self = this; const attrs = self.get('attrs'); const mappedData = []; - const data = this.layerSource.propertiesData; + // const data = this.layerSource.propertiesData; + const data = this.layerSource.data.dataArray; for (let i = 0; i < data.length; i++) { const record = data[i]; const newRecord = {}; @@ -362,18 +361,17 @@ export default class Layer extends Base { } } } + newRecord.coordinates = record.coordinates; mappedData.push(newRecord); } - - this.StyleData = mappedData; - return mappedData; + this.layerData = mappedData; } // 更新地图映射 _updateMaping() { const self = this; const attrs = self.get('attrs'); - const data = this.layerSource.propertiesData; + const data = this.layerSource.data.dataArray; for (let i = 0; i < data.length; i++) { const record = data[i]; for (const attrName in attrs) { @@ -385,10 +383,10 @@ export default class Layer extends Base { for (let j = 0; j < values.length; j++) { const val = values[j]; const name = names[j]; - this.StyleData[i][name] = (Util.isArray(val) && val.length === 1) ? val[0] : val; // 只有一个值时返回第一个属性值 + this.layerData[i][name] = (Util.isArray(val) && val.length === 1) ? val[0] : val; // 只有一个值时返回第一个属性值 } } else { - this.StyleData[i][names[0]] = values.length === 1 ? values[0] : values; + this.layerData[i][names[0]] = values.length === 1 ? values[0] : values; } attr.neadUpdate = true; @@ -468,6 +466,7 @@ export default class Layer extends Base { pickingMesh.material.setUniformsValue('u_zoom', zoom); }; this._pickingMesh.add(pickingMesh); + } _setPickingId() { this._pickingId = this.getPickingId(); @@ -532,13 +531,13 @@ export default class Layer extends Base { */ _updateFilter(object) { this._updateMaping(); - const filterData = this.StyleData; + const filterData = this.layerData; this._activeIds = null; // 清空选中元素 const colorAttr = object.geometry.attributes.a_color; const pickAttr = object.geometry.attributes.pickingId; pickAttr.array.forEach((id, index) => { id = Math.abs(id); - const color = [ ...this.StyleData[id - 1].color ]; + const color = [ ...this.layerData[id - 1].color ]; id = Math.abs(id); const item = filterData[id - 1]; if (item.hasOwnProperty('filter') && item.filter === false) { @@ -584,7 +583,7 @@ export default class Layer extends Base { const pickingId = this.layerMesh.geometry.attributes.pickingId.array; const colorAttr = this.layerMesh.geometry.attributes.a_color; this._activeIds.forEach(index => { - const color = this.StyleData[index].color; + const color = this.layerData[index].color; const firstId = pickingId.indexOf(index + 1); for (let i = firstId; i < pickingId.length; i++) { if (pickingId[i] === index + 1) { diff --git a/src/core/scene.js b/src/core/scene.js index b85ba35a5a..38e3879c48 100644 --- a/src/core/scene.js +++ b/src/core/scene.js @@ -3,8 +3,8 @@ import { LAYER_MAP } from '../layer'; import Base from './base'; import LoadImage from './image'; import WorkerPool from './worker'; -import { MapProvider } from '../map/provider'; -import GaodeMap from '../map/gaodeMap'; +// import { MapProvider } from '../map/AMap'; +import { getMap } from '../map/index'; import Global from '../global'; import { compileBuiltinModules } from '../geom/shader'; export default class Scene extends Base { @@ -31,16 +31,14 @@ export default class Scene extends Base { } _initMap() { this.mapContainer = this.get('id'); - this._container = document.getElementById(this.mapContainer); - const Map = new MapProvider(this.mapContainer, this._attrs); + this.mapType = this.get('mapType') || 'amap'; + const MapProvider = getMap(this.mapType); + const Map = new MapProvider(this._attrs); + Map.mixMap(this); + this._container = document.getElementById(Map.container); + // const Map = new MapProvider(this.mapContainer, this._attrs); Map.on('mapLoad', () => { this._initEngine(Map.renderDom); - const sceneMap = new GaodeMap(Map.map); - // eslint-disable-next-line - Object.getOwnPropertyNames(sceneMap.__proto__).forEach((key)=>{ - // eslint-disable-next-line - if ('key' !== 'constructor') { this.__proto__[key] = sceneMap.__proto__[key]; } - }); this.map = Map.map; Map.asyncCamera(this._engine); this.initLayer(); @@ -101,8 +99,10 @@ export default class Scene extends Base { 'dblclick' ]; events.forEach(event => { - this.map.on(event, e => { + + this._container.addEventListener(event, e => { // 要素拾取 + e.pixel || (e.pixel = e.point); this._engine._picking.pickdata(e); }, false); }); diff --git a/src/core/source.js b/src/core/source.js index 3a61aead88..259ab32179 100644 --- a/src/core/source.js +++ b/src/core/source.js @@ -1,17 +1,15 @@ -/* - * @Author: ThinkGIS - * @Date: 2018-06-08 11:19:06 - * @Last Modified by: mikey.zhaopeng - * @Last Modified time: 2018-11-01 11:50:43 - */ + import Base from './base'; const Controller = require('./controller/index'); -import { aProjectFlat } from '../geo/project'; +import { getTransform, getParser } from '../source'; +import { getMap } from '../map/index'; export default class Source extends Base { getDefaultCfg() { return { data: null, defs: {}, + parser: {}, + transforms: [], scales: { }, options: {} @@ -19,26 +17,40 @@ export default class Source extends Base { } constructor(cfg) { super(cfg); - + const transform = this.get('transforms'); + this._transforms = transform || []; this._initControllers(); - this.prepareData(); + // 数据解析 + this._excuteParser(); + // 数据转换 统计,聚合,分类 + this._executeTrans(); + // 坐标转换 + this._projectCoords(); } - - // 标准化数据 - prepareData() { + _excuteParser() { + const parser = this.get('parser'); + const { type = 'geojson' } = parser; const data = this.get('data'); - this.propertiesData = [];// 临时使用 - this.geoData = []; - - data.coordinates.forEach(geo => { - const coord = this._coordProject(geo); - this.geoData.push(coord); - this.propertiesData.push([]); + this.data = getParser(type)(data, parser); + } + /** + * 数据统计 + */ + _executeTrans() { + const trans = this._transforms; + trans.forEach(tran => { + const { type } = tran; + this.data = getTransform(type)(this.data, tran); + }); + this._transforms = trans; + } + _projectCoords() { + this.data.dataArray.forEach(data => { + data.coordinates = this._coordProject(data.coordinates); }); } - createScale(field) { - const data = this.propertiesData; + const data = this.data.dataArray; const scales = this.get('scales'); let scale = scales[field]; const scaleController = this.get('scaleController'); @@ -50,6 +62,8 @@ export default class Source extends Base { } _initControllers() { const defs = this.get('defs'); + const mapType = this.get('mapType'); + this.projectFlat = getMap(mapType).project; const scaleController = new Controller.Scale({ defs }); @@ -83,9 +97,14 @@ export default class Source extends Base { } _coorConvert(geo) { - const ll = aProjectFlat(geo); - return [ ll.x, -ll.y, geo[2] || 0 ]; + const ll = this.projectFlat(geo); + return [ ll.x, ll.y, geo[2] || 0 ]; } + getSelectFeature(featureId) { + const data = this.get('data'); + // 如果是GeoJSON 数据返回原数 + return data.features ? data.features[featureId] : this.data.dataArray[featureId]; + } } diff --git a/src/core/three.js b/src/core/three.js index 75cbe58b5d..03359e840d 100644 --- a/src/core/three.js +++ b/src/core/three.js @@ -4,6 +4,7 @@ export { Scene } from 'three/src/scenes/Scene.js'; export { WebGLRenderer } from 'three/src/renderers/WebGLRenderer.js'; export { CanvasTexture } from 'three/src/textures/CanvasTexture.js'; export { Object3D } from 'three/src/core/Object3D.js'; +export { Group } from 'three/src/objects/Group'; export { Clock } from 'three/src/core/Clock'; export { Points } from 'three/src/objects/Points.js'; export { LineSegments } from 'three/src/objects/LineSegments.js'; diff --git a/src/geo/lngLat.js b/src/geo/lngLat.js index edc7b59576..b635918f0c 100644 --- a/src/geo/lngLat.js +++ b/src/geo/lngLat.js @@ -1,20 +1,75 @@ -export class LatLng { - constructor(lat, lng, alt) { - if (isNaN(lat) || isNaN(lng)) { - throw new Error('Invalid LatLng object: (' + lat + ', ' + lng + ')'); - } - this.lat = +lat; - this.lng = +lng; - if (alt !== undefined) { - this.alt = +alt; - } +self._wkHandlers={};; - } - equal() { + function _prep_h17(){function a(b,c,d,e,g,k){var l=[0,0,0,0,0],n=d.slice(0,4).concat(l),p=[],s=Math.PI/180*6,A=void 0,I=void 0,A=d.slice(0,2),D=m(e),F=m(g),I=q.normalize(h(D).fg(h(A))),C=q.normalize(h(F).fg(h(A)));q.OK(I,k)?(A=q.oD(I),I=q.oD(C)):(A=q.oD(C),I=q.oD(I),k=[F,D],D=k[0],F=k[1],g=[g,e],e=g[0],g=g[1]);D=Math.ceil(Math.abs(I-A)/s);30<=D&&(D=60-D);for(k=0;kMath.sqrt(3)/2&&(d=Math.sqrt(3)/2);c=c.oJ(d)}return c}function g(a,c,e){if(void 0===e||!0===e)b.push(a[0],a[1]),b.push(-c.y,c.x,0,0),b.push(m,0,0),d.push(a[2]);if(void 0===e||!1===e)b.push(a[0],a[1]),b.push(c.y,-c.x,0,0),b.push(m,0,0),d.push(a[2])}for(var k=a[0],l=a[a.length-1],m=0,n=void 0;k[0]===l[0]&&k[1]===l[1]&&k!==l;)a.pop(),l=a[a.length-1];a.push(k);a.push(a[1]);a.unshift(l);var p=a.length;a.forEach(function(a,d, k){var l=k[d-1];k=k[d+1];var r=void 0;l&&(m+=q.Fd(a,l));if(0===d||d===p-1)0===d?(r=q.normalize(h(k[0]-a[0],k[1]-a[1])),c.push(0,1,2)):(r=q.normalize(h(a[0]-l[0],a[1]-l[1])),d=b.length/9+2,c.push(d-3,d-1,d-2)),g(a,r);else{d=q.normalize(h(a[0]-l[0],a[1]-l[1]));k=q.normalize(h(k[0]-a[0],k[1]-a[1]));l=q.normalize(d.multiply(-1).mi(k));n=q.OK(l,d);g(a,e(d,k),!0);g(a,e(d,k),!1);g(a,e(d,k),!0);g(a,e(d,k),!1);a=b.length/9-4;k=a+2;var r=9*a,s=r+9,x=s+9,B=x+9;d=Math.abs(q.cos(d,l)/q.sin(d,l));n?(b[r+7]=d,b[s+ 7]=-d,b[x+7]=-d,b[B+7]=d):(b[r+7]=-d,b[s+7]=d,b[x+7]=d,b[B+7]=-d);c.push(a,a-1,a+1);c.push(k,k+1,k+2)}})}function e(c,d,e){function g(a,b){if(p)for(;0=a&&(a+=2*Math.PI);return a}},s={mi:function(a){return h(this.x+a.x,this.y+a.y)},fg:function(a){return h(this.x-a.x,this.y-a.y)},multiply:function(a){return"number"===typeof a?h(this.x*a,this.y*a):this.x*a.x+this.y*a.y},oJ:function(a){return h(this.x/a,this.y/a)},NC:function(a){var b=a.y;return this.x===a.x&&this.y===b}};return{parse:function(a,b){var h=a.lineJoin,h=void 0===h?"bevel":h,k= a.lineCap,k=void 0===k?"butt":k,l=a.Zda,l=void 0===l?!1:l,m=a.tn,n=void 0===m?!1:m,p=a.LX,m=a.Iia,q=void 0===m?!0:m,m=a.Sda,s=[],A=[],I=g(a.Nr,void 0===p?!0:p),p=[];l?(d(I,s,A,p),h=s.length,[0,1,2,h/9-1,h/9-2].forEach(function(a){s[9*a+8]=-1})):(c(I,s,A,h,n,p),e(I,s,A,k,p));q&&(s=new Float32Array(s),A=65535=h||b.jn;if(d||b){d=1 { + const { color, id } = element; + const [ x, y, z ] = element.coordinates; + attribute.vertices.push(x, y, z); + attribute.miter.push(-1, -1); + attribute.vertices.push(x, y, z); + attribute.miter.push(1, 1); + attribute.vertices.push(x, y, z); + attribute.miter.push(-1, 1); + attribute.vertices.push(x, y, z); + attribute.miter.push(-1, -1); + attribute.vertices.push(x, y, z); + attribute.miter.push(1, -1); + attribute.vertices.push(x, y, z); + attribute.miter.push(1, 1); + attribute.colors.push(...color); + attribute.colors.push(...color); + attribute.colors.push(...color); + attribute.colors.push(...color); + attribute.colors.push(...color); + attribute.colors.push(...color); + attribute.pickingIds.push(id, id, id, id, id, id); + }); + return attribute; +} diff --git a/src/geom/buffer/image.js b/src/geom/buffer/image.js index 70b52aed51..262151b149 100644 --- a/src/geom/buffer/image.js +++ b/src/geom/buffer/image.js @@ -4,8 +4,9 @@ import * as THREE from '../../core/three'; export default class ImageBuffer extends BufferBase { geometryBuffer() { - const coordinates = this.get('coordinates'); - const images = this.get('image'); + const layerData = this.get('layerData'); + const coordinates = layerData[0].coordinates; + const images = layerData[0].images; const positions = [ ...coordinates[0], coordinates[1][0], coordinates[0][1], 0, ...coordinates[1], diff --git a/src/geom/buffer/line.js b/src/geom/buffer/line.js index a73006f07c..880ac2dc95 100644 --- a/src/geom/buffer/line.js +++ b/src/geom/buffer/line.js @@ -3,8 +3,7 @@ import { lineShape } from '../shape'; export default class LineBuffer extends BufferBase { geometryBuffer() { - const coordinates = this.get('coordinates'); - const properties = this.get('properties'); + const layerData = this.get('layerData'); const shapeType = this.shapeType = this.get('shapeType'); const positions = []; const positionsIndex = []; @@ -16,16 +15,16 @@ export default class LineBuffer extends BufferBase { this.attributes = this._getArcLineAttributes(); return; } - coordinates.forEach((geo, index) => { - const props = properties[index]; - const attrData = this._getShape(geo, props, index); + layerData.forEach((item, index) => { + const props = item; + const attrData = this._getShape(item.coordinates, props, index); positions.push(...attrData.positions); positionsIndex.push(...attrData.indexes); if (attrData.hasOwnProperty('instances')) { instances.push(...attrData.instances); } }); - this.bufferStruct.style = properties; + this.bufferStruct.style = layerData; this.bufferStruct.verts = positions; this.bufferStruct.indexs = positionsIndex; if (instances.length > 0) { @@ -50,17 +49,16 @@ export default class LineBuffer extends BufferBase { } _getArcLineAttributes() { - const coordinates = this.get('coordinates'); - const properties = this.get('properties'); + const layerData = this.get('layerData'); const positions = []; const colors = []; const indexArray = []; const sizes = []; const instances = []; - coordinates.forEach((geo, index) => { - const props = properties[index]; + layerData.forEach(item => { + const props = item; const positionCount = positions.length / 3; - const attrData = this._getShape(geo, props, positionCount); + const attrData = this._getShape(item.coordinates, props, positionCount); positions.push(...attrData.positions); colors.push(...attrData.colors); indexArray.push(...attrData.indexArray); @@ -76,8 +74,7 @@ export default class LineBuffer extends BufferBase { }; } _getMeshLineAttributes() { - const coordinates = this.get('coordinates'); - const properties = this.get('properties'); + const layerData = this.get('layerData'); const { lineType } = this.get('style'); const positions = []; const pickingIds = []; @@ -87,10 +84,10 @@ export default class LineBuffer extends BufferBase { const indexArray = []; const sizes = []; const attrDistance = []; - coordinates.forEach((geo, index) => { - const props = properties[index]; + layerData.forEach(item => { + const props = item; const positionCount = positions.length / 3; - const attr = lineShape.Line(geo, props, positionCount, (lineType !== 'soild')); + const attr = lineShape.Line(item.coordinates, props, positionCount, (lineType !== 'soild')); positions.push(...attr.positions); normal.push(...attr.normal); miter.push(...attr.miter); diff --git a/src/geom/buffer/point/fillBuffer.js b/src/geom/buffer/point/fillBuffer.js index 84d257c3ee..7179959827 100644 --- a/src/geom/buffer/point/fillBuffer.js +++ b/src/geom/buffer/point/fillBuffer.js @@ -3,7 +3,7 @@ import * as THREE from '../../../core/three'; import * as polygonShape from '../../shape/polygon'; import * as polygonPath from '../../shape/path'; import Util from '../../../util'; -export default function fillBuffer(coordinates, properties) { +export default function fillBuffer(layerData) { const attribute = { vertices: [], normals: [], @@ -14,8 +14,8 @@ export default function fillBuffer(coordinates, properties) { faceUv: [] }; - coordinates.forEach((geo, index) => { - let { size, shape, color, id } = properties[index]; + layerData.forEach(item => { + let { size, shape, color, id, coordinates } = item; let polygon = null; const path = polygonPath[shape](); if (pointShape['2d'].indexOf(shape) !== -1) { @@ -27,7 +27,7 @@ export default function fillBuffer(coordinates, properties) { } else { throw new Error('Invalid shape type: ' + shape); } - toPointShapeAttributes(polygon, geo, { size, shape, color, id }, attribute); + toPointShapeAttributes(polygon, coordinates, { size, shape, color, id }, attribute); }); return attribute; diff --git a/src/geom/buffer/point/imageBuffer.js b/src/geom/buffer/point/imageBuffer.js index 6bc37b052a..383134b6d9 100644 --- a/src/geom/buffer/point/imageBuffer.js +++ b/src/geom/buffer/point/imageBuffer.js @@ -1,4 +1,4 @@ -export default function ImageBuffer(coordinates, properties, opt) { +export default function ImageBuffer(layerData, opt) { const attributes = { vertices: [], colors: [], @@ -7,10 +7,10 @@ export default function ImageBuffer(coordinates, properties, opt) { pickingIds: [], uv: [] }; - coordinates.forEach((pos, index) => { - const { color, size, id, shape } = properties[index]; + layerData.forEach(item => { + const { color, size, id, shape, coordinates } = item; const { x, y } = opt.imagePos[shape]; - attributes.vertices.push(...pos); + attributes.vertices.push(...coordinates); attributes.colors.push(...color); attributes.pickingIds.push(id); attributes.sizes.push(size * window.devicePixelRatio); // diff --git a/src/geom/buffer/point/normalBuffer.js b/src/geom/buffer/point/normalBuffer.js index d35fd4217b..aaa50ee424 100644 --- a/src/geom/buffer/point/normalBuffer.js +++ b/src/geom/buffer/point/normalBuffer.js @@ -1,13 +1,13 @@ -export default function NormalBuffer(coordinates, properties) { +export default function NormalBuffer(layerData) { const attributes = { vertices: [], colors: [], sizes: [], pickingIds: [] }; - coordinates.forEach((pos, index) => { - const { color, size, id } = properties[index]; - attributes.vertices.push(...pos); + layerData.forEach(item => { + const { color, size, id, coordinates} = item; + attributes.vertices.push(...coordinates); attributes.colors.push(...color); attributes.pickingIds.push(id); attributes.sizes.push(size); diff --git a/src/geom/buffer/point/strokeBuffer.js b/src/geom/buffer/point/strokeBuffer.js index c71726cbd6..eff757e3c6 100644 --- a/src/geom/buffer/point/strokeBuffer.js +++ b/src/geom/buffer/point/strokeBuffer.js @@ -3,7 +3,7 @@ import * as polygonShape from '../../shape/polygon'; import * as lineShape from '../../shape/line'; import { pointShape } from '../../../global'; import Util from '../../../util'; -export default function StrokeBuffer(coordinates, properties, style) { +export default function StrokeBuffer(layerData, style) { const attribute = { shapes: [], normal: [], @@ -15,8 +15,8 @@ export default function StrokeBuffer(coordinates, properties, style) { colors: [] }; const { stroke, strokeWidth } = style; - coordinates.forEach((geo, index) => { - let { size, shape, id } = properties[index]; + layerData.forEach(item => { + let { size, shape, id, coordinates } = item; const path = polygonPath[shape](); const positionsIndex = attribute.miter.length; let polygon = null; @@ -33,7 +33,7 @@ export default function StrokeBuffer(coordinates, properties, style) { } else { throw new Error('Invalid shape type: ' + shape); } - polygonLineBuffer(polygon, geo, size, attribute); + polygonLineBuffer(polygon, coordinates, size, attribute); }); return attribute; diff --git a/src/geom/buffer/point/textBuffer.js b/src/geom/buffer/point/textBuffer.js index 0bbab7d759..1d68acb3b1 100644 --- a/src/geom/buffer/point/textBuffer.js +++ b/src/geom/buffer/point/textBuffer.js @@ -9,7 +9,7 @@ const metrics = { family: 'ios9', size: 24 }; -export default function TextBuffer(coordinates, properties, style) { +export default function TextBuffer(layerData, style) { EventEmitter.call(this); const attributes = { originPoints: [], @@ -21,7 +21,7 @@ export default function TextBuffer(coordinates, properties, style) { const { textOffset = [ 0, 0 ] } = style; const chars = []; const textChars = {}; - properties.forEach(element => { + layerData.forEach(element => { let text = element.shape || ''; text = text.toString(); for (let j = 0; j < text.length; j++) { @@ -33,9 +33,9 @@ export default function TextBuffer(coordinates, properties, style) { } }); loadTextInfo(chars, (chars, texture) => { - properties.forEach((element, index) => { + layerData.forEach(element => { const size = element.size; - const pos = coordinates[index]; + const pos = layerData.coordinates; const pen = { x: textOffset[0], y: textOffset[1] }; let text = element.shape || ''; text = text.toString(); diff --git a/src/geom/buffer/polygon.js b/src/geom/buffer/polygon.js index c90172802a..60c585d872 100644 --- a/src/geom/buffer/polygon.js +++ b/src/geom/buffer/polygon.js @@ -3,22 +3,21 @@ import BufferBase from './bufferBase'; export default class PolygonBuffer extends BufferBase { geometryBuffer() { - const coordinates = this.get('coordinates'); - const properties = this.get('properties'); + const layerData = this.get('layerData'); const shape = this.get('shape'); const positions = []; const faceUv = []; const sizes = []; const positionsIndex = []; let indexCount = 0; - this.bufferStruct.style = properties; - const isExtrude = properties[0].hasOwnProperty('size'); + this.bufferStruct.style = layerData; + const isExtrude = layerData[0].hasOwnProperty('size'); // indices, normals, colors, UVs - coordinates.forEach((geo, index) => { - const heightValue = properties[index].size; - let extrudeData = polygonShape[shape](geo); + layerData.forEach(item => { + const heightValue = item.size; + let extrudeData = polygonShape[shape](item.coordinates); if (isExtrude && shape === 'extrude') { - extrudeData = polygonShape.extrude(geo); + extrudeData = polygonShape.extrude(item.coordinates); extrudeData.positions = extrudeData.positions.map(pos => { pos[2] *= heightValue; return pos; @@ -48,7 +47,7 @@ export default class PolygonBuffer extends BufferBase { this.bufferStruct.indices = positionsIndex; this.bufferStruct.position = positions; this.bufferStruct.indexCount = indexCount; - this.bufferStruct.style = properties; + this.bufferStruct.style = layerData; this.bufferStruct.faceUv = faceUv; this.bufferStruct.sizes = sizes; if (shape !== 'line') { diff --git a/src/geom/buffer/raster.js b/src/geom/buffer/raster.js index 32fa14a3ba..9f62192699 100644 --- a/src/geom/buffer/raster.js +++ b/src/geom/buffer/raster.js @@ -3,8 +3,8 @@ import { colorScales } from '../../attr/colorscales'; import * as THREE from '../../core/three'; export class RasterBuffer extends BufferBase { geometryBuffer() { - const coordinates = this.get('coordinates'); - + const layerData = this.get('layerData'); + const { coordinates, width, data, height } = layerData.dataArray[0]; const positions = [ ...coordinates[0], coordinates[1][0], coordinates[0][1], 0, @@ -14,9 +14,8 @@ export class RasterBuffer extends BufferBase { coordinates[0][0], coordinates[1][1], 0 ]; const imgPosUv = [ 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0 ]; - const raster = this.get('raster'); const size = this.get('size'); - const texture = new THREE.DataTexture(new Float32Array(raster.data), raster.width, raster.height, THREE.LuminanceFormat, THREE.FloatType); + const texture = new THREE.DataTexture(new Float32Array(data), width, height, THREE.LuminanceFormat, THREE.FloatType); texture.generateMipmaps = true; texture.needsUpdate = true; const colors = this.get('rampColors'); @@ -28,7 +27,7 @@ export class RasterBuffer extends BufferBase { this.bufferStruct.u_extent = [ coordinates[0][0], coordinates[0][1], coordinates[1][0], coordinates[1][1] ]; this.bufferStruct.u_colorTexture = colorTexture; // 颜色表‘= - const triangles = this._buildTriangles(raster, size, this.bufferStruct.u_extent); + const triangles = this._buildTriangles(width, height, size, this.bufferStruct.u_extent); const attributes = { vertices: new Float32Array(triangles.vertices), uvs: new Float32Array(triangles.uvs), @@ -78,9 +77,8 @@ export class RasterBuffer extends BufferBase { texture1.needsUpdate = true; return texture1; } - _buildTriangles(raster, size = 1, extent) { + _buildTriangles(width, height, size = 1, extent) { // const extent = [ 73.482190241, 3.82501784112, 135.106618732, 57.6300459963 ] - const { width, height } = raster; const indices = []; const vertices = []; const uvs = []; diff --git a/src/geom/buffer/text.js b/src/geom/buffer/text.js index 099f6d217f..5f906352b4 100644 --- a/src/geom/buffer/text.js +++ b/src/geom/buffer/text.js @@ -13,12 +13,11 @@ export default class TextBuffer extends BufferBase { family: 'ios9', size: 24 }; - const coordinates = this.get('coordinates'); - const properties = this.get('properties'); + const layerData = this.get('layerData'); const { textOffset = [ 0, 0 ] } = this.get('style'); const chars = []; const textChars = {}; - properties.forEach(element => { + layerData.forEach(element => { let text = element.shape || ''; text = text.toString(); for (let j = 0; j < text.length; j++) { @@ -39,9 +38,9 @@ export default class TextBuffer extends BufferBase { const originPoints = []; const textSizes = []; const textOffsets = []; - properties.forEach((element, index) => { + layerData.forEach(element => { const size = element.size; - const pos = coordinates[index]; + const pos = element.coordinates; // const pen = { x: pos[0] - dimensions.advance / 2, y: pos[1] }; const pen = { x: textOffset[0], y: textOffset[1] }; let text = element.shape || ''; @@ -53,7 +52,7 @@ export default class TextBuffer extends BufferBase { this._drawGlyph(pos, text[i], pen, size, colors, textureElements, originPoints, textSizes, textOffsets, color); } }); - this.bufferStruct.style = properties; + this.bufferStruct.style = layerData; this.attributes = { originPoints, textSizes, diff --git a/src/geom/material/grid.js b/src/geom/material/grid.js new file mode 100644 index 0000000000..65db262fcf --- /dev/null +++ b/src/geom/material/grid.js @@ -0,0 +1,31 @@ +import grid_frag from '../shader/grid_frag.glsl'; +import grid_vert from '../shader/grid_vert.glsl'; +import Material from './material'; + + +export default class GridMaterial extends Material { + getDefaultParameters() { + return { + uniforms: { + u_opacity: { value: 1.0 }, + u_time: { value: 0 }, + u_xOffset: { value: 0.01 }, + u_yOffset: { value: 0.01 }, + u_coverage: { value: 0.8 } + }, + defines: { + + } + }; + } + constructor(_uniforms, _defines, parameters) { + super(parameters); + const { uniforms, defines } = this.getDefaultParameters(); + this.uniforms = Object.assign(uniforms, this.setUniform(_uniforms)); + this.type = 'GridMaterial'; + this.defines = Object.assign(defines, _defines); + this.vertexShader = grid_vert; + this.fragmentShader = grid_frag; + this.transparent = true; + } +} diff --git a/src/geom/material/polygonMaterial.js b/src/geom/material/polygonMaterial.js index da8a598122..cd606fb8f1 100644 --- a/src/geom/material/polygonMaterial.js +++ b/src/geom/material/polygonMaterial.js @@ -1,28 +1,5 @@ import Material from './material'; import { getModule } from '../../util/shaderModule'; -// export default function PolygonMaterial(options) { -// const material = new Material({ -// uniforms: { -// u_opacity: { value: options.u_opacity || 1.0 }, -// u_texture: { value: options.u_texture }, -// u_time: { value: options.u_time || 0 }, -// u_zoom: { value: options.u_zoom || 0 }, -// u_baseColor: { value: options.u_baseColor || [ 1.0, 0, 0, 1.0 ] }, -// u_brightColor: { value: options.u_brightColor || [ 1.0, 0, 0, 1.0 ] }, -// u_windowColor: { value: options.u_windowColor || [ 1.0, 0, 0, 1.0 ] }, -// u_near: { value: options.u_near || 0.0 }, -// u_far: { value: options.u_far || 1.0 } -// }, -// vertexShader: polygon_vert, -// fragmentShader: polygon_frag, -// transparent: true, -// defines: { -// TEXCOORD_0: !!options.u_texture -// } -// }); -// return material; -// } - export default class PolygonMaterial extends Material { getDefaultParameters() { return { diff --git a/src/geom/shader/grid_frag.glsl b/src/geom/shader/grid_frag.glsl new file mode 100644 index 0000000000..042dde511e --- /dev/null +++ b/src/geom/shader/grid_frag.glsl @@ -0,0 +1,8 @@ + precision highp float; + uniform float u_opacity; + varying vec4 v_color; + void main() { + vec4 color = v_color; + gl_FragColor = color; + gl_FragColor.a =color.a*u_opacity; +} \ No newline at end of file diff --git a/src/geom/shader/grid_vert.glsl b/src/geom/shader/grid_vert.glsl new file mode 100644 index 0000000000..90c68a3b70 --- /dev/null +++ b/src/geom/shader/grid_vert.glsl @@ -0,0 +1,15 @@ +precision highp float; +attribute vec2 miter; +attribute vec4 a_color; +uniform float u_xOffset; +uniform float u_yOffset; +uniform float u_coverage; +varying vec4 v_color; + +void main() { + mat4 matModelViewProjection = projectionMatrix * modelViewMatrix; + v_color = a_color; + float x = position.x + miter.x * u_xOffset * u_coverage; + float y = position.y + miter.y * u_yOffset * u_coverage; + gl_Position = matModelViewProjection * vec4(x, y, position.z, 1.0); +} \ No newline at end of file diff --git a/src/geom/shader/point_frag.glsl b/src/geom/shader/point_frag.glsl index eecea0605c..10e11d0f09 100644 --- a/src/geom/shader/point_frag.glsl +++ b/src/geom/shader/point_frag.glsl @@ -1,7 +1,8 @@ precision highp float; -#pragma import "common" +#define PI 3.14159265359 +#define TWO_PI 6.28318530718 uniform float u_strokeWidth; uniform vec4 u_stroke; diff --git a/src/geom/shader/polygon_vert.glsl b/src/geom/shader/polygon_vert.glsl index 7d35a1d249..eba0b62d02 100644 --- a/src/geom/shader/polygon_vert.glsl +++ b/src/geom/shader/polygon_vert.glsl @@ -15,7 +15,7 @@ varying float v_size; void main() { float scale = pow(2.0,(20.0 - u_zoom)); - mat4 matModelViewProjection = projectionMatrix * modelViewMatrix; + mat4 matModelViewProjection = projectionMatrix * modelViewMatrix * 100.; vec3 newposition = position; // newposition.x -= 128.0; #ifdef SHAPE diff --git a/src/layer/heatmap.js b/src/layer/heatmap.js new file mode 100644 index 0000000000..f9971a55da --- /dev/null +++ b/src/layer/heatmap.js @@ -0,0 +1,28 @@ +import Layer from '../core/layer'; +import gridBuffer from '../geom/buffer/heatmap/grid'; +import DrawGrid from './render/heatmap/gird'; + +export default class HeatMapLayer extends Layer { + shape(type) { + this.shapeType = type; + return this; + } + render() { + this._prepareRender(); + return this; + } + _prepareRender() { + this.init(); + this.type = 'heatmap'; + const style = this.get('styleOptions'); + const { xOffset, yOffset } = this.layerSource.data; + this._buffer = new gridBuffer(this.layerData); + const config = { + ...style, + xOffset, + yOffset + }; + const girdMesh = new DrawGrid(this._buffer, config); + this.add(girdMesh); + } +} diff --git a/src/layer/imageLayer.js b/src/layer/imageLayer.js index f3092da117..92e9a60b59 100644 --- a/src/layer/imageLayer.js +++ b/src/layer/imageLayer.js @@ -1,26 +1,19 @@ import Layer from '../core/layer'; import * as THREE from '../core/three'; -import imageSource from '../source/imageSource'; import ImageBuffer from '../geom/buffer/image'; // import ImageGeometry from '../geom/bufferGeometry/image'; import ImageMaterial from '../geom/material/imageMaterial'; export default class imageLayer extends Layer { - source(data, cfg = {}) { - cfg.mapType = this.get('mapType'); - cfg.data = data; - this.layerSource = new imageSource(cfg); - return this; - } render() { this.init(); this.type = 'image'; const source = this.layerSource; const { opacity } = this.get('styleOptions'); // 加载 完成事件 - source.on('imageLoaded', () => { + source.data.images.then(images => { + this.layerData[0].images = images; const buffer = new ImageBuffer({ - coordinates: source.geoData, - image: source.image + layerData: this.layerData }); this.initGeometry(buffer.attributes); const material = new ImageMaterial({ diff --git a/src/layer/index.js b/src/layer/index.js index 5e8fef27c6..1c2cad2fdf 100644 --- a/src/layer/index.js +++ b/src/layer/index.js @@ -4,17 +4,14 @@ import PointLayer from './pointLayer'; import LineLayer from './lineLayer'; import ImageLayer from './imageLayer'; import RasterLayer from './rasterLayer'; +import HeatMapLayer from './heatmap'; registerLayer('PolygonLayer', PolygonLayer); registerLayer('PointLayer', PointLayer); registerLayer('LineLayer', LineLayer); registerLayer('ImageLayer', ImageLayer); registerLayer('RasterLayer', RasterLayer); +registerLayer('HeatMapLayer', HeatMapLayer); export { LAYER_MAP } from './factory'; -export { default as PolygonLayer } from './polygonLayer'; -export { default as PointLayer } from './pointLayer'; -export { default as LineLayer } from './lineLayer'; -export { default as ImageLayer } from './imageLayer'; -export { default as RasterLayer } from './rasterLayer'; diff --git a/src/layer/lineLayer.js b/src/layer/lineLayer.js index 4d40755100..c83c3f0a88 100644 --- a/src/layer/lineLayer.js +++ b/src/layer/lineLayer.js @@ -12,11 +12,10 @@ export default class LineLayer extends Layer { this.type = 'polyline'; this.init(); const source = this.layerSource; - const StyleData = this.StyleData; + const layerData = this.layerData; const style = this.get('styleOptions'); const buffer = this._buffer = new LineBuffer({ - coordinates: source.geoData, - properties: StyleData, + layerData, shapeType: this.shapeType, style }); diff --git a/src/layer/pointLayer.js b/src/layer/pointLayer.js index 74163f82b4..7acbdfbf53 100644 --- a/src/layer/pointLayer.js +++ b/src/layer/pointLayer.js @@ -45,12 +45,12 @@ export default class PointLayer extends Layer { case 'fill' :// 填充图形 { if (fill !== 'none') { // 是否填充 - const attributes = PointBuffer.FillBuffer(source.geoData, this.StyleData, style); + const attributes = PointBuffer.FillBuffer(this.layerData, style); const meshfill = drawPoint.DrawFill(attributes, this.get('styleOptions')); this.add(meshfill); } if (stroke !== 'none') { // 是否绘制边界 - const lineAttribute = PointBuffer.StrokeBuffer(source.geoData, this.StyleData, style); + const lineAttribute = PointBuffer.StrokeBuffer(this.layerData, style); const meshStroke = drawPoint.DrawStroke(lineAttribute, this.get('styleOptions')); this.add(meshStroke, 'line'); } @@ -58,14 +58,14 @@ export default class PointLayer extends Layer { } case 'image':// 绘制图片标注 { - const imageAttribute = PointBuffer.ImageBuffer(source.geoData, this.StyleData, { imagePos: this.scene.image.imagePos }); + const imageAttribute = PointBuffer.ImageBuffer(this.layerData, { imagePos: this.scene.image.imagePos }); const imageMesh = drawPoint.DrawImage(imageAttribute, { ...style, texture: this.scene.image.texture }); this.add(imageMesh); break; } case 'normal' : // 原生点 { - const normalAttribute = PointBuffer.NormalBuffer(source.geoData, this.StyleData, style); + const normalAttribute = PointBuffer.NormalBuffer(this.layerData, style); const normalPointMesh = drawPoint.DrawNormal(normalAttribute, style); this.add(normalPointMesh); break; @@ -77,11 +77,11 @@ export default class PointLayer extends Layer { _getShape() { let shape = null; - if (!this.StyleData[0].hasOwnProperty('shape')) { + if (!this.layerData[0].hasOwnProperty('shape')) { return 'normal'; } - for (let i = 0; i < this.StyleData.length; i++) { - shape = this.StyleData[i].shape; + for (let i = 0; i < this.layerData.length; i++) { + shape = this.layerData[i].shape; if (shape !== undefined) { break; } @@ -102,8 +102,7 @@ export default class PointLayer extends Layer { const styleOptions = this.get('styleOptions'); const buffer = new TextBuffer({ type: this.shapeType, - coordinates: source.geoData, - properties: this.StyleData, + layerData: this.layerData, style: this.get('styleOptions') }); diff --git a/src/layer/polygonLayer.js b/src/layer/polygonLayer.js index 53e7c9903e..ba37ed3b87 100644 --- a/src/layer/polygonLayer.js +++ b/src/layer/polygonLayer.js @@ -21,11 +21,9 @@ export default class PolygonLayer extends Layer { _prepareRender() { this.init(); this.type = 'polygon'; - const source = this.layerSource; this._buffer = new PolygonBuffer({ shape: this.shape, - coordinates: source.geoData, - properties: this.StyleData + layerData: this.layerData }); this.add(this._getLayerRender()); } diff --git a/src/layer/rasterLayer.js b/src/layer/rasterLayer.js index 7a68dc8530..cb5d9f41a9 100644 --- a/src/layer/rasterLayer.js +++ b/src/layer/rasterLayer.js @@ -1,16 +1,10 @@ import Layer from '../core/layer'; import * as THREE from '../core/three'; -import RasterSource from '../source/rasterSource'; import RasterMaterial from '../geom/material/rasterMaterial'; import { RasterBuffer } from '../geom/buffer/raster'; export default class RasterLayer extends Layer { - source(data, cfg = {}) { - cfg.mapType = this.get('mapType'); - cfg.data = data; - this.layerSource = new RasterSource(cfg); - return this; - } + render() { this.type = 'raster'; this.init(); @@ -18,18 +12,18 @@ export default class RasterLayer extends Layer { // 加载 完成事件 const styleOptions = this.get('styleOptions'); const buffer = new RasterBuffer({ - coordinates: source.geoData, - raster: source.rasterData, + layerData: source.data, rampColors: styleOptions.rampColors }); this.initGeometry(buffer.attributes); + const rasterConfig = source.data.dataArray[0]; const material = new RasterMaterial({ u_texture: buffer.bufferStruct.u_raster, u_colorTexture: buffer.bufferStruct.u_colorTexture, u_opacity: 1.0, u_extent: buffer.bufferStruct.u_extent, - u_min: source.rasterData.min, - u_max: source.rasterData.max, + u_min: rasterConfig.min, + u_max: rasterConfig.max, u_dimension: buffer.attributes.dimension }); diff --git a/src/layer/render/heatmap/gird.js b/src/layer/render/heatmap/gird.js new file mode 100644 index 0000000000..5aa4b07796 --- /dev/null +++ b/src/layer/render/heatmap/gird.js @@ -0,0 +1,21 @@ +import * as THREE from '../../../core/three'; +import GridMaterial from '../../../geom/material/grid'; +export default function DrawGrid(attributes, style) { + const { opacity, xOffset, yOffset, coverage } = style; + const geometry = new THREE.BufferGeometry(); + geometry.addAttribute('position', new THREE.Float32BufferAttribute(attributes.vertices, 3)); + geometry.addAttribute('miter', new THREE.Float32BufferAttribute(attributes.miter, 2)); + geometry.addAttribute('a_color', new THREE.Float32BufferAttribute(attributes.colors, 4)); + geometry.addAttribute('pickingId', new THREE.Float32BufferAttribute(attributes.pickingIds, 1)); + const material = new GridMaterial({ + u_opacity: opacity, + u_xOffset: xOffset, + u_yOffset: yOffset, + u_coverage: coverage + }, { + SHAPE: false + }); + const gridMesh = new THREE.Mesh(geometry, material); + return gridMesh; +} + diff --git a/src/map/provider.js b/src/map/AMap.js similarity index 57% rename from src/map/provider.js rename to src/map/AMap.js index 19763e8f45..e54615b94a 100644 --- a/src/map/provider.js +++ b/src/map/AMap.js @@ -1,18 +1,34 @@ import Base from '../core/base'; +import { scene } from '../global'; import * as Theme from '../theme/index'; import Util from '../util'; -import { scene } from '../global'; const DEG2RAD = Math.PI / 180; -export class MapProvider extends Base { +export default class GaodeMap extends Base { getDefaultCfg() { return Util.assign(scene, { resizeEnable: true, viewMode: '3D' }); } - constructor(container, cfg) { + static project(lnglat) { + const maxs = 85.0511287798; + const lat = Math.max(Math.min(maxs, lnglat[1]), -maxs); + const scale = 256 << 20; + let d = Math.PI / 180; + let x = lnglat[0] * d; + let y = lat * d; + y = Math.log(Math.tan((Math.PI / 4) + (y / 2))); + const a = 0.5 / Math.PI, + b = 0.5, + c = -0.5 / Math.PI; + d = 0.5; + x = scale * (a * x + b) - 215440491; + y = -(scale * (c * y + d) - 106744817); + return { x, y }; + } + constructor(cfg) { super(cfg); - this.container = container; + this.container = this.get('id'); this.initMap(); this.addOverLayer(); setTimeout(() => { @@ -85,4 +101,31 @@ export class MapProvider extends Base { this.renderDom.id = 'l7_canvaslayer'; canvasContainer.appendChild(this.renderDom); } + mixMap(scene) { + const map = this.map; + scene.getZoom = () => { return map.getZoom(); }; + scene.getCenter = () => { return map.getCenter(); }; + scene.getSize = () => { return map.getSize(); }; + scene.getPitch = () => { return map.getPitch(); }; + scene.getRotation = () => { return map.getRotation(); }; + scene.getStatus = () => { return map.getStatus(); }; + scene.getScale = () => { return map.getScale(); }; + scene.getZoom = () => { return map.getZoom(); }; + scene.setZoom = () => { return map.setZoom(); }; + scene.setBounds = () => { return map.setBounds(); }; + scene.setRotation = () => { return map.setRotation(); }; + scene.zoomIn = () => { return map.zoomIn(); }; + scene.setRotation = () => { return map.setRotation(); }; + scene.zoomOut = () => { return map.zoomOut(); }; + scene.panTo = () => { return map.panTo(); }; + scene.panBy = () => { return map.panBy(); }; + scene.setPitch = () => { return map.setPitch(); }; + scene.pixelToLngLat = () => { return map.pixelToLngLat(); }; + scene.lngLatToPixel = () => { return map.lngLatToPixel(); }; + scene.setMapStyle = () => { return map.setMapStyle(); }; + scene.containerToLngLat = pixel => { + const ll = new AMap.Pixel(pixel.x, pixel.y); + return map.containerToLngLat(ll); + }; + } } diff --git a/src/map/baseMap.js b/src/map/baseMap.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/map/gaodeMap.js b/src/map/gaodeMap.js index bdd98f54f5..4b4ff3eb5c 100644 --- a/src/map/gaodeMap.js +++ b/src/map/gaodeMap.js @@ -21,7 +21,7 @@ export default class GaodeMap { return this.map.getStatus(); } getScale() { - return this.getScale(); + return this.map.getScale(); } setZoom(zoom) { return this.map.setZoom(zoom); diff --git a/src/map/index.js b/src/map/index.js new file mode 100644 index 0000000000..ae5b7dbb7d --- /dev/null +++ b/src/map/index.js @@ -0,0 +1,22 @@ +import MapBox from './mapbox'; +import { default as AMap } from './AMap'; +export { + AMap, + MapBox +}; +const MapType = { + amap: AMap, + mapbox: MapBox +}; +export const getMap = type => { + return MapType[type.toLowerCase()]; +}; + +export const registerMap = (type, map) => { + if (getMap(type)) { + throw new Error(`Map type '${type}' existed.`); + } + map.type = type; + // 存储到 map 中 + MapType[type.toLowerCase()] = map; +}; diff --git a/src/map/mapbox.js b/src/map/mapbox.js new file mode 100644 index 0000000000..8eebadc8ef --- /dev/null +++ b/src/map/mapbox.js @@ -0,0 +1,154 @@ +import Base from '../core/base'; +import Util from '../util'; +import { scene } from '../global'; +import * as THREE from '../core/three'; +const WORLD_SIZE = 512; +const MERCATOR_A = 6378137.0; +const WORLD_SCALE = 1 / 100; +const PROJECTION_WORLD_SIZE = WORLD_SIZE / (MERCATOR_A * Math.PI) / 2; +export default class MapBox extends Base { + getDefaultCfg() { + return Util.assign(scene, { + resizeEnable: true, + viewMode: '3D' + }); + } + static project(lnglat) { + const d = Math.PI / 180; + const x = -MERCATOR_A * lnglat[0] * d * PROJECTION_WORLD_SIZE; + const y = -MERCATOR_A * Math.log(Math.tan((Math.PI * 0.25) + (0.5 * lnglat[1] * d))) * PROJECTION_WORLD_SIZE; + return { x, y }; + } + constructor(cfg) { + super(cfg); + this.container = this.get('container'); + this.initMap(); + this.addOverLayer(); + setTimeout(() => { + this.emit('mapLoad'); + }, 100); + + } + + initMap() { + mapboxgl.accessToken = 'pk.eyJ1IjoibHp4dWUiLCJhIjoiYnhfTURyRSJ9.Ugm314vAKPHBzcPmY1p4KQ'; + this.map = new mapboxgl.Map(this._attrs); + } + asyncCamera(engine) { + this.engine = engine; + const camera = engine._camera; + const scene = engine.world; + const pickScene = engine._picking.world; + camera.matrixAutoUpdate = false; + scene.position.x = scene.position.y = WORLD_SIZE / 2; + scene.matrixAutoUpdate = false; + pickScene.position.x = pickScene.position.y = WORLD_SIZE / 2; + pickScene.matrixAutoUpdate = false; + this.updateCamera(); + this.map.on('move', () => { + this.updateCamera(); + }); + } + updateCamera() { + const engine = this.engine; + const scene = engine.world; + const pickScene = engine._picking.world; + const camera = engine._camera; + // Build a projection matrix, paralleling the code found in Mapbox GL JS + const fov = 0.6435011087932844; + const cameraToCenterDistance = 0.5 / Math.tan(fov / 2) * this.map.transform.height * WORLD_SCALE; + const halfFov = fov / 2; + const groundAngle = Math.PI / 2 + this.map.transform._pitch; + const topHalfSurfaceDistance = Math.sin(halfFov) * cameraToCenterDistance / Math.sin(Math.PI - groundAngle - halfFov); + + // Calculate z distance of the farthest fragment that should be rendered. + const furthestDistance = Math.cos(Math.PI / 2 - this.map.transform._pitch) * topHalfSurfaceDistance + cameraToCenterDistance; + + // Add a bit extra to avoid precision problems when a fragment's distance is exactly `furthestDistance` + let farZ = furthestDistance * 1.1; + if (this.pitch > 50) { + farZ = 1000; + } + const { x, y } = this.map.transform.point; + camera.projectionMatrix = this.makePerspectiveMatrix(fov, this.map.transform.width / this.map.transform.height, 1, farZ); + const cameraWorldMatrix = new THREE.Matrix4(); + const cameraTranslateZ = new THREE.Matrix4().makeTranslation(0, 0, cameraToCenterDistance); + const cameraRotateX = new THREE.Matrix4().makeRotationX(this.map.transform._pitch); + const cameraRotateZ = new THREE.Matrix4().makeRotationZ(this.map.transform.angle); + const cameraTranslateXY = new THREE.Matrix4().makeTranslation(x * WORLD_SCALE, -y * WORLD_SCALE, 0); + // const cameraTranslateCenter = new THREE.Matrix4().makeTranslation(0, 0, cameraToCenterDistance); + // Unlike the Mapbox GL JS camera, separate camera translation and rotation out into its world matrix + // If this is applied directly to the projection matrix, it will work OK but break raycasting + cameraWorldMatrix + .premultiply(cameraTranslateZ) + .premultiply(cameraRotateX) + .premultiply(cameraRotateZ) + .premultiply(cameraTranslateXY); + + camera.matrixWorld.copy(cameraWorldMatrix); + + const zoomPow = this.map.transform.scale * WORLD_SCALE; + // Handle scaling and translation of objects in the map in the world's matrix transform, not the camera + const scale = new THREE.Matrix4(); + const translateCenter = new THREE.Matrix4(); + const translateMap = new THREE.Matrix4(); + const rotateMap = new THREE.Matrix4(); + scale + .makeScale(zoomPow, zoomPow, 1.0); + translateCenter + .makeTranslation(WORLD_SIZE / 2, -WORLD_SIZE / 2, 0); + translateMap + .makeTranslation(-this.map.transform.x, this.map.transform.y, 0); + rotateMap + .makeRotationZ(Math.PI); + scene.matrix = new THREE.Matrix4(); + scene.matrix + .premultiply(rotateMap) + .premultiply(translateCenter) + .premultiply(scale); + pickScene.matrix = new THREE.Matrix4(); + pickScene.matrix + .premultiply(rotateMap) + .premultiply(translateCenter) + .premultiply(scale); + } + makePerspectiveMatrix(fovy, aspect, near, far) { + const out = new THREE.Matrix4(); + const f = 1.0 / Math.tan(fovy / 2), + nf = 1 / (near - far); + const newMatrix = [ + f / aspect, 0, 0, 0, + 0, f, 0, 0, + 0, 0, (far + near) * nf, -1, + 0, 0, (2 * far * near) * nf, 0 + ]; + out.elements = newMatrix; + return out; + } + + projectFlat(lnglat) { + return this.map.lngLatToGeodeticCoord(lnglat); + } + getCenter() { + return this.map.getCenter(); + } + getCenterFlat() { + return this.projectFlat(this.getCenter()); + } + addOverLayer() { + const canvasContainer = document.getElementById(this.container); + this.canvasContainer = canvasContainer; + this.renderDom = document.createElement('div'); + this.renderDom.style.cssText += 'position: absolute;top: 0; z-index:10;height: 100%;width: 100%;pointer-events: none;'; + this.renderDom.id = 'l7_canvaslayer'; + canvasContainer.appendChild(this.renderDom); + } + mixMap(scene) { + const map = this.map; + scene.getZoom = () => { return map.getZoom(); }; + scene.getCenter = () => { return map.getCenter(); }; + scene.getPitch = () => { return map.getPitch(); }; + scene.containerToLngLat = point => { return map.unproject(point); }; + + } +} diff --git a/src/source/csvSource.js b/src/source/csvSource.js deleted file mode 100644 index e5ce0b9834..0000000000 --- a/src/source/csvSource.js +++ /dev/null @@ -1,69 +0,0 @@ -import Source from '../core/source'; -import FeatureIndex from '../geo/featureIndex'; -import { csvParse } from 'd3-dsv'; -export default class CSVSource extends Source { - prepareData() { - this.type = 'csv'; - const data = this.get('data'); - const x = this.get('x'); - const y = this.get('y'); - const x1 = this.get('x1'); - const y1 = this.get('y1'); - const coords = this.get('coordinates'); - this.propertiesData = [];// 临时使用 - this.geoData = []; - let csvdata = data; - Array.isArray(csvdata) || (csvdata = csvParse(data)); - this.propertiesData = csvdata; - csvdata.forEach((col, featureIndex) => { - let coordinates = []; - if (col.coordinates) { - coordinates = col.coordinates; - } - if (x && y) { coordinates = [ col[x], col[y] ]; } // 点数据 - if (x1 && y1) { // 弧线 或者线段 - coordinates = [[ col[x], col[y] ], [ col[x1], col[y1] ]]; - } - if (coords && col.coords) { coordinates = col.coords; } - col._id = featureIndex + 1; - this._coordProject(coordinates); - this.geoData.push(this._coordProject(coordinates)); - }); - } - - featureIndex() { - const data = this.get('data'); - this.featureIndex = new FeatureIndex(data); - } - getSelectFeatureId(featureId) { - return [ featureId ]; - } - getSelectFeature(featureId) { - return this.propertiesData[featureId]; - - } - _getCoord(geo) { - if (geo.geometry) { - // GeoJSON feature - geo = geo.geometry.coordinates; - } else if (geo.coordinates) { - // GeoJSON geometry - geo = geo.coordinates; - } - return geo; - } - _coordProject(geo) { - if (Array.isArray(geo[0][0])) { - return geo.map(coor => { - return this._coordProject(coor); - }); - } - if (!Array.isArray(geo[0])) { - return this._coorConvert(geo); - } - return geo.map(coor => { - return this._coorConvert(coor); - }); - } - -} diff --git a/src/source/factory.js b/src/source/factory.js new file mode 100644 index 0000000000..37629b9e99 --- /dev/null +++ b/src/source/factory.js @@ -0,0 +1,11 @@ + +const TRANSFORMS = {}; +const PARSERS = {}; +export const getParser = type => PARSERS[type]; +export const registerParser = (type, parserFunction) => { + PARSERS[type] = parserFunction; +}; +export const getTransform = type => TRANSFORMS[type]; +export const registerTransform = (type, transFunction) => { + TRANSFORMS[type] = transFunction; +}; diff --git a/src/source/geojsonSource.js b/src/source/geojsonSource.js deleted file mode 100644 index 1b1c012568..0000000000 --- a/src/source/geojsonSource.js +++ /dev/null @@ -1,45 +0,0 @@ -import Source from '../core/source'; -import * as turfMeta from '@turf/meta'; -import { default as cleanCoords } from '@turf/clean-coords'; -import { getCoords } from '@turf/invariant'; -import FeatureIndex from '../geo/featureIndex'; - -export default class GeojsonSource extends Source { - prepareData() { - this.type = 'geojson'; - const data = this.get('data'); - this.propertiesData = []; - this.geoData = []; - turfMeta.flattenEach(data, (currentFeature, featureIndex) => { - const coord = getCoords(cleanCoords(currentFeature)); - this.geoData.push(this._coordProject(coord)); - currentFeature.properties._id = featureIndex + 1; - this.propertiesData.push(currentFeature.properties); - }); - } - featureIndex() { - const data = this.get('data'); - this.featureIndex = new FeatureIndex(data); - } - getSelectFeatureId(featureId) { - const data = this.get('data'); - const selectFeatureIds = []; - let featureStyleId = 0; - turfMeta.flattenEach(data, (currentFeature, featureIndex/* , multiFeatureIndex*/) => { - if (featureIndex === (featureId)) { - selectFeatureIds.push(featureStyleId); - } - featureStyleId++; - if (featureIndex > featureId) { - return; - } - }); - return selectFeatureIds; - - } - getSelectFeature(featureId) { - const data = this.get('data'); - return data.features[featureId]; - } - -} diff --git a/src/source/imageSource.js b/src/source/imageSource.js deleted file mode 100644 index 137f5a0772..0000000000 --- a/src/source/imageSource.js +++ /dev/null @@ -1,37 +0,0 @@ -import Source from '../core/source'; -import { getImage } from '../util/ajax'; -export default class ImageSource extends Source { - prepareData() { - this.type = 'image'; - const extent = this.get('extent'); - const lb = this._coorConvert(extent.slice(0, 2)); - const tr = this._coorConvert(extent.slice(2, 4)); - this.geoData = [ lb, tr ]; - this.propertiesData = []; - this._loadData(); - } - _loadData() { - const url = this.get('data'); - this.image = []; - if (typeof (url) === 'string') { - getImage({ url }, (err, img) => { - this.image = img; - this.emit('imageLoaded'); - }); - } else { - const imageCount = url.length; - let imageindex = 0; - url.forEach(item => { - getImage({ url: item }, (err, img) => { - imageindex++; - this.image.push(img); - if (imageindex === imageCount) { - this.emit('imageLoaded'); - } - - }); - }); - - } - } -} diff --git a/src/source/index.js b/src/source/index.js index ea6b260c09..ff88ba484e 100644 --- a/src/source/index.js +++ b/src/source/index.js @@ -1,5 +1,23 @@ -export { default as geojson } from './geojsonSource'; -export { default as csv } from './csvSource'; -export { default as array } from './csvSource'; -export { default as basic } from '../core/source'; -export { default as imageSource } from './imageSource'; +// source parser + +import geojson from './parser/geojson'; +import image from './parser/image'; +import csv from './parser/csv'; +import json from './parser/json'; +import raster from './parser/raster'; + +import { registerTransform, registerParser } from './factory'; +import { aggregatorToGrid } from './transform/grid'; +import { map } from './transform/map'; + +registerParser('geojson', geojson); +registerParser('image', image); +registerParser('csv', csv); +registerParser('json', json); +registerParser('raster', raster); +// 注册transform + +registerTransform('grid', aggregatorToGrid); +registerTransform('map', map); + +export { getTransform, registerTransform, getParser, registerParser } from './factory'; diff --git a/src/source/parser/csv.js b/src/source/parser/csv.js new file mode 100644 index 0000000000..f727d18209 --- /dev/null +++ b/src/source/parser/csv.js @@ -0,0 +1,23 @@ +import { csvParse } from 'd3-dsv'; +export default function csv(data, cfg) { + const { x, y, x1, y1 } = cfg; + const csvdata = csvParse(data); + const resultdata = []; + csvdata.forEach((col, featureIndex) => { + let coordinates = []; + if (x && y) { coordinates = [ col[x], col[y] ]; } // 点数据 + if (x1 && y1) { // 弧线 或者线段 + coordinates = [[ col[x], col[y] ], [ col[x1], col[y1] ]]; + } + col._id = featureIndex + 1; + const dataItem = { + ...col, + coordinates + + }; + resultdata.push(dataItem); + }); + return { + dataArray: resultdata + }; +} diff --git a/src/source/parser/geojson.js b/src/source/parser/geojson.js new file mode 100644 index 0000000000..6385fa0d42 --- /dev/null +++ b/src/source/parser/geojson.js @@ -0,0 +1,19 @@ +import * as turfMeta from '@turf/meta'; +import { default as cleanCoords } from '@turf/clean-coords'; +import { getCoords } from '@turf/invariant'; + +export default function geoJSON(data) { + const resultData = []; + turfMeta.flattenEach(data, (currentFeature, featureIndex) => { // 多个polygon 拆成一个 + const coord = getCoords(cleanCoords(currentFeature)); + const dataItem = { + ...currentFeature.properties, + coordinates: coord, + _id: featureIndex + 1 + }; + resultData.push(dataItem); + }); + return { + dataArray: resultData + }; +} diff --git a/src/source/parser/image.js b/src/source/parser/image.js new file mode 100644 index 0000000000..e4a6f99ddf --- /dev/null +++ b/src/source/parser/image.js @@ -0,0 +1,41 @@ +import { getImage } from '../../util/ajax'; +export default function image(data, cfg) { + const { extent } = cfg; + + const images = new Promise(resolve => { + loadData(data, res => { + resolve(res); + }); + }); + const resultData = { + images, + _id: 1, + dataArray: [{ coordinates: [[ extent[0], extent[1] ], [ extent[2], extent[3] ]] }] + }; + return resultData; +} +function loadData(data, done) { + const url = data; + let image = []; + if (typeof (url) === 'string') { + getImage({ url }, (err, img) => { + image = img; + done(image); + }); + } else { + const imageCount = url.length; + let imageindex = 0; + url.forEach(item => { + getImage({ url: item }, (err, img) => { + imageindex++; + image.push(img); + if (imageindex === imageCount) { + done(image); + } + + }); + }); + + } + return image; +} diff --git a/src/source/parser/json.js b/src/source/parser/json.js new file mode 100644 index 0000000000..37128bebce --- /dev/null +++ b/src/source/parser/json.js @@ -0,0 +1,21 @@ +export default function json(data, cfg) { + const { x, y, x1, y1 } = cfg; + const resultdata = []; + data.forEach((col, featureIndex) => { + let coordinates = []; + if (x && y) { coordinates = [ col[x], col[y] ]; } // 点数据 + if (x1 && y1) { // 弧线 或者线段 + coordinates = [[ col[x], col[y] ], [ col[x1], col[y1] ]]; + } + col._id = featureIndex + 1; + const dataItem = { + ...col, + coordinates + + }; + resultdata.push(dataItem); + }); + return { + dataArray: resultdata + }; +} diff --git a/src/source/parser/raster.js b/src/source/parser/raster.js new file mode 100644 index 0000000000..7d33903a23 --- /dev/null +++ b/src/source/parser/raster.js @@ -0,0 +1,15 @@ +export default function raster(data, cfg) { + const { extent, width, height, min, max } = cfg; + const resultData = { + _id: 1, + dataArray: [ + { + data, + width, + height, + min, + max, + coordinates: [[ extent[0], extent[1] ], [ extent[2], extent[3] ]] }] + }; + return resultData; +} diff --git a/src/source/rainSource.js b/src/source/rainSource.js deleted file mode 100644 index 6808878742..0000000000 --- a/src/source/rainSource.js +++ /dev/null @@ -1,31 +0,0 @@ -import imageSource from './imageSource'; -export class RainSource extends imageSource { - prepareData() { - const extent = this.get('extent'); - const lb = this._coorConvert(extent.slice(0, 2)); - const tr = this._coorConvert(extent.slice(2, 4)); - this.extent = [ lb, tr ]; - this.propertiesData = []; - this._genaratePoints(); - this._loadData(); - } - _genaratePoints() { - const numParticles = 512 * 512; - - const particleRes = this.particleRes = Math.ceil(Math.sqrt(numParticles)); - const numPoints = particleRes * particleRes; - const particleState = []; - const particleState0 = new Uint8ClampedArray(numPoints * 4); - const particleState1 = new Uint8ClampedArray(numPoints * 4); - const emptyPixels = new Uint8ClampedArray(numPoints * 4); - for (let i = 0; i < particleState0.length; i++) { - particleState0[i] = Math.floor(Math.random() * 256); // randomize the initial particle positions - } - this.particleIndices = new Float32Array(numPoints); - for (let i = 0; i < numPoints; i++) this.particleIndices[i] = i; - this.particleImage0 = new ImageData(particleState0, particleRes, particleRes); - this.particleImage1 = new ImageData(particleState1, particleRes, particleRes); - this.backgroundImage = new ImageData(emptyPixels, particleRes, particleRes); - this.geoData = particleState; - } -} diff --git a/src/source/rasterSource.js b/src/source/rasterSource.js deleted file mode 100644 index 2439422dce..0000000000 --- a/src/source/rasterSource.js +++ /dev/null @@ -1,20 +0,0 @@ -import Source from '../core/source'; -export default class RasterSource extends Source { - prepareData() { - this.type = 'raster'; - const extent = this.get('extent'); - const lb = this._coorConvert(extent.slice(0, 2)); - const tr = this._coorConvert(extent.slice(2, 4)); - this.geoData = [ lb, tr ]; - this.propertiesData = []; - this.rasterData = { - data: this.get('data'), - width: this.get('width'), - height: this.get('height'), - min: this.get('min'), - max: this.get('max') - }; - - } - -} diff --git a/src/source/transform/grid.js b/src/source/transform/grid.js new file mode 100644 index 0000000000..d2ace3476c --- /dev/null +++ b/src/source/transform/grid.js @@ -0,0 +1,101 @@ +/** + * 生成四边形热力图 + */ +import * as statistics from './statistics'; + +const R_EARTH = 6378000; + +/** + * 计算方格密度图 + * @param {*} data 经纬度数据 和属性数据 + * @param {*} size 半径大小 单位 km + * @return + */ +export function aggregatorToGrid(data, option) { + const dataArray = data.dataArray; + const { size = 10 } = option; + const { gridHash, gridOffset } = _pointsGridHash(dataArray, size); + const layerData = _getGridLayerDataFromGridHash(gridHash, gridOffset, option); + return { + xOffset: gridOffset.xOffset / 360 * (256 << 20) / 2, + yOffset: gridOffset.xOffset / 360 * (256 << 20) / 2, + dataArray: layerData + }; +} + +function _pointsGridHash(dataArray, size) { + let latMin = Infinity; + let latMax = -Infinity; + let pLat; + for (let index = 0; index < dataArray.length; index++) { + const point = dataArray[index]; + pLat = point.coordinates[1]; + if (Number.isFinite(pLat)) { + latMin = pLat < latMin ? pLat : latMin; + latMax = pLat > latMax ? pLat : latMax; + } + + } + // const centerLat = (latMin + latMax) / 2; + const centerLat = 34.54083; + const gridOffset = _calculateGridLatLonOffset(size, centerLat); + if (gridOffset.xOffset <= 0 || gridOffset.yOffset <= 0) { + return { gridHash: {}, gridOffset }; + } + const gridHash = {}; + for (let index = 0; index < dataArray.length; index++) { + const point = dataArray[index]; + const lat = point.coordinates[1]; + const lng = point.coordinates[0]; + + if (Number.isFinite(lat) && Number.isFinite(lng)) { + const latIdx = Math.floor((lat + 90) / gridOffset.yOffset); + const lonIdx = Math.floor((lng + 180) / gridOffset.xOffset); + const key = `${latIdx}-${lonIdx}`; + + gridHash[key] = gridHash[key] || { count: 0, points: [] }; + gridHash[key].count += 1; + gridHash[key].points.push(point); + } + } + + return { gridHash, gridOffset }; +} +// 计算网格偏移量 +function _calculateGridLatLonOffset(cellSize, latitude) { + const yOffset = _calculateLatOffset(cellSize); + const xOffset = _calculateLonOffset(latitude, cellSize); + return { yOffset, xOffset }; +} + +function _calculateLatOffset(dy) { + return (dy / R_EARTH) * (180 / Math.PI); +} + +function _calculateLonOffset(lat, dx) { + return ((dx / R_EARTH) * (180 / Math.PI)) / Math.cos((lat * Math.PI) / 180); +} +function _getGridLayerDataFromGridHash(gridHash, gridOffset, option) { + return Object.keys(gridHash).reduce((accu, key, i) => { + const idxs = key.split('-'); + const latIdx = parseInt(idxs[0], 10); + const lonIdx = parseInt(idxs[1], 10); + const item = {}; + if (option.field && option.method) { + const columns = getColumn(gridHash[key].points, option.field); + item[option.method] = statistics[option.method](columns); + } + Object.assign(item, { + _id: i + 1, + coordinates: [ -180 + gridOffset.xOffset * lonIdx, -90 + gridOffset.yOffset * latIdx ], + count: gridHash[key].count + }); + accu.push(item); + return accu; + }, []); +} +function getColumn(data, columnName) { + return data.map(item => { + return item[columnName]; + }); +} diff --git a/src/source/transform/hexagon.js b/src/source/transform/hexagon.js new file mode 100644 index 0000000000..df796c7450 --- /dev/null +++ b/src/source/transform/hexagon.js @@ -0,0 +1,41 @@ +import { hexbin } from 'd3-hexbin'; +import { aProjectFlat, unProjectFlat } from '../../geo/project'; +import * as statistics from './statistics'; +const R_EARTH = 6378000; +export function pointToHexbin(data, option) { + const dataArray = data.dataArray; + const { size = 10 } = option; + const pixlSize = size / (2 * Math.PI * R_EARTH) * (256 << 20) / 2; + const screenPoints = dataArray.map(point => { + const { x, y } = aProjectFlat(point.coordinates); + return { + ...point, + coordinates: [ x, y ] + }; + }); + + const newHexbin = hexbin() + .radius(pixlSize) + .x(d => d.coordinates[0]) + .y(d => d.coordinates[1]); + const hexbinBins = newHexbin(screenPoints); + const result = { + size: pixlSize + }; + result.dataArray = hexbinBins.map((hex, index) => { + if (option.field && option.method) { + const columns = getColumn(hex, option.field); + hex[option.method] = statistics[option.method](columns); + } + return { + coordinates: unProjectFlat([ hex.x, hex.y ]), + id: index + 1 + }; + }); + return result; +} +function getColumn(data, columnName) { + return data.map(item => { + return item[columnName]; + }); +} diff --git a/src/source/transform/map.js b/src/source/transform/map.js new file mode 100644 index 0000000000..47c66e1005 --- /dev/null +++ b/src/source/transform/map.js @@ -0,0 +1,7 @@ +export function map(data, options) { + const { callback } = options; + if (callback) { + data.dataArray = data.dataArray.map(callback); + } + return data; +} diff --git a/src/source/transform/statistics.js b/src/source/transform/statistics.js new file mode 100644 index 0000000000..2a7a317846 --- /dev/null +++ b/src/source/transform/statistics.js @@ -0,0 +1,10 @@ +/* 支持 'max', 'mean', 'median', 'min', 'mode', 'product', 'standardDeviation', + * 'sum', 'sumSimple', 'variance', 'count', 'distinct' + */ +export { default as min } from 'simple-statistics/src/min'; +export { default as max } from 'simple-statistics/src/max'; +export { default as mean } from 'simple-statistics/src/mean'; +export { default as sum } from 'simple-statistics/src/sum'; +export { default as median } from 'simple-statistics/src/median'; +export { default as standardDeviation } from 'simple-statistics/src/standard_deviation'; + diff --git a/test/asset/data/point.js b/test/asset/data/point.js new file mode 100644 index 0000000000..6fc7183712 --- /dev/null +++ b/test/asset/data/point.js @@ -0,0 +1,1490 @@ +export const pointData = [ + { grid_y: 121055, count: 7600, grid_x: 480481 }, + { grid_y: 121055, count: 3800, grid_x: 480487 }, + { grid_y: 121055, count: 3800, grid_x: 480493 }, + { grid_y: 121055, count: 7600, grid_x: 480501 }, + { grid_y: 121055, count: 3800, grid_x: 480502 }, + { grid_y: 121055, count: 15200, grid_x: 480503 }, + { grid_y: 121055, count: 3800, grid_x: 480504 }, + { grid_y: 121055, count: 7600, grid_x: 480505 }, + { grid_y: 121055, count: 3800, grid_x: 480506 }, + { grid_y: 121055, count: 3800, grid_x: 480507 }, + { grid_y: 121055, count: 3800, grid_x: 480512 }, + { grid_y: 121055, count: 3800, grid_x: 480530 }, + { grid_y: 121056, count: 3800, grid_x: 480494 }, + { grid_y: 121056, count: 3800, grid_x: 480496 }, + { grid_y: 121056, count: 7600, grid_x: 480501 }, + { grid_y: 121056, count: 11400, grid_x: 480502 }, + { grid_y: 121056, count: 7600, grid_x: 480503 }, + { grid_y: 121056, count: 7600, grid_x: 480504 }, + { grid_y: 121056, count: 3800, grid_x: 480506 }, + { grid_y: 121056, count: 3800, grid_x: 480508 }, + { grid_y: 121056, count: 3800, grid_x: 480509 }, + { grid_y: 121056, count: 3800, grid_x: 480520 }, + { grid_y: 121056, count: 3800, grid_x: 480524 }, + { grid_y: 121057, count: 11400, grid_x: 480484 }, + { grid_y: 121057, count: 3800, grid_x: 480489 }, + { grid_y: 121057, count: 3800, grid_x: 480500 }, + { grid_y: 121057, count: 3800, grid_x: 480502 }, + { grid_y: 121057, count: 3800, grid_x: 480509 }, + { grid_y: 121057, count: 3800, grid_x: 480515 }, + { grid_y: 121057, count: 3800, grid_x: 480522 }, + { grid_y: 121057, count: 3800, grid_x: 480523 }, + { grid_y: 121057, count: 15200, grid_x: 480524 }, + { grid_y: 121057, count: 3800, grid_x: 480525 }, + { grid_y: 121057, count: 3800, grid_x: 480527 }, + { grid_y: 121058, count: 3800, grid_x: 480478 }, + { grid_y: 121058, count: 3800, grid_x: 480482 }, + { grid_y: 121058, count: 3800, grid_x: 480485 }, + { grid_y: 121058, count: 3800, grid_x: 480486 }, + { grid_y: 121058, count: 3800, grid_x: 480487 }, + { grid_y: 121058, count: 3800, grid_x: 480490 }, + { grid_y: 121058, count: 3800, grid_x: 480497 }, + { grid_y: 121058, count: 3800, grid_x: 480499 }, + { grid_y: 121058, count: 7600, grid_x: 480501 }, + { grid_y: 121058, count: 3800, grid_x: 480502 }, + { grid_y: 121058, count: 7600, grid_x: 480503 }, + { grid_y: 121058, count: 3800, grid_x: 480521 }, + { grid_y: 121058, count: 3800, grid_x: 480522 }, + { grid_y: 121058, count: 3800, grid_x: 480523 }, + { grid_y: 121058, count: 3800, grid_x: 480524 }, + { grid_y: 121058, count: 3800, grid_x: 480528 }, + { grid_y: 121059, count: 3800, grid_x: 480495 }, + { grid_y: 121059, count: 3800, grid_x: 480499 }, + { grid_y: 121059, count: 3800, grid_x: 480500 }, + { grid_y: 121059, count: 7600, grid_x: 480502 }, + { grid_y: 121059, count: 7600, grid_x: 480503 }, + { grid_y: 121059, count: 3800, grid_x: 480504 }, + { grid_y: 121059, count: 34200, grid_x: 480507 }, + { grid_y: 121059, count: 3800, grid_x: 480511 }, + { grid_y: 121059, count: 3800, grid_x: 480516 }, + { grid_y: 121060, count: 7600, grid_x: 480491 }, + { grid_y: 121060, count: 7600, grid_x: 480496 }, + { grid_y: 121060, count: 3800, grid_x: 480497 }, + { grid_y: 121060, count: 3800, grid_x: 480498 }, + { grid_y: 121060, count: 7600, grid_x: 480499 }, + { grid_y: 121060, count: 7600, grid_x: 480500 }, + { grid_y: 121060, count: 7600, grid_x: 480502 }, + { grid_y: 121060, count: 3800, grid_x: 480505 }, + { grid_y: 121060, count: 3800, grid_x: 480506 }, + { grid_y: 121060, count: 3800, grid_x: 480511 }, + { grid_y: 121060, count: 3800, grid_x: 480513 }, + { grid_y: 121060, count: 3800, grid_x: 480514 }, + { grid_y: 121061, count: 3800, grid_x: 480491 }, + { grid_y: 121061, count: 7600, grid_x: 480497 }, + { grid_y: 121061, count: 7600, grid_x: 480499 }, + { grid_y: 121061, count: 11400, grid_x: 480500 }, + { grid_y: 121061, count: 3800, grid_x: 480501 }, + { grid_y: 121061, count: 7600, grid_x: 480502 }, + { grid_y: 121061, count: 15200, grid_x: 480503 }, + { grid_y: 121061, count: 11400, grid_x: 480504 }, + { grid_y: 121061, count: 7600, grid_x: 480505 }, + { grid_y: 121061, count: 3800, grid_x: 480506 }, + { grid_y: 121061, count: 3800, grid_x: 480507 }, + { grid_y: 121061, count: 3800, grid_x: 480511 }, + { grid_y: 121061, count: 3800, grid_x: 480526 }, + { grid_y: 121062, count: 15200, grid_x: 480489 }, + { grid_y: 121062, count: 7600, grid_x: 480491 }, + { grid_y: 121062, count: 7600, grid_x: 480492 }, + { grid_y: 121062, count: 7600, grid_x: 480499 }, + { grid_y: 121062, count: 11400, grid_x: 480500 }, + { grid_y: 121062, count: 3800, grid_x: 480502 }, + { grid_y: 121062, count: 3800, grid_x: 480503 }, + { grid_y: 121062, count: 7600, grid_x: 480504 }, + { grid_y: 121062, count: 3800, grid_x: 480505 }, + { grid_y: 121062, count: 3800, grid_x: 480517 }, + { grid_y: 121062, count: 7600, grid_x: 480522 }, + { grid_y: 121062, count: 3800, grid_x: 480527 }, + { grid_y: 121062, count: 3800, grid_x: 480530 }, + { grid_y: 121063, count: 3800, grid_x: 480488 }, + { grid_y: 121063, count: 7600, grid_x: 480489 }, + { grid_y: 121063, count: 15200, grid_x: 480492 }, + { grid_y: 121063, count: 3800, grid_x: 480493 }, + { grid_y: 121063, count: 3800, grid_x: 480497 }, + { grid_y: 121063, count: 7600, grid_x: 480499 }, + { grid_y: 121063, count: 7600, grid_x: 480500 }, + { grid_y: 121063, count: 15200, grid_x: 480501 }, + { grid_y: 121063, count: 11400, grid_x: 480502 }, + { grid_y: 121063, count: 3800, grid_x: 480516 }, + { grid_y: 121063, count: 3800, grid_x: 480518 }, + { grid_y: 121063, count: 3800, grid_x: 480522 }, + { grid_y: 121063, count: 11400, grid_x: 480524 }, + { grid_y: 121063, count: 3800, grid_x: 480525 }, + { grid_y: 121064, count: 7600, grid_x: 480488 }, + { grid_y: 121064, count: 3800, grid_x: 480489 }, + { grid_y: 121064, count: 7600, grid_x: 480490 }, + { grid_y: 121064, count: 3800, grid_x: 480491 }, + { grid_y: 121064, count: 3800, grid_x: 480493 }, + { grid_y: 121064, count: 3800, grid_x: 480495 }, + { grid_y: 121064, count: 3800, grid_x: 480496 }, + { grid_y: 121064, count: 15200, grid_x: 480499 }, + { grid_y: 121064, count: 3800, grid_x: 480500 }, + { grid_y: 121064, count: 15200, grid_x: 480501 }, + { grid_y: 121064, count: 7600, grid_x: 480502 }, + { grid_y: 121064, count: 3800, grid_x: 480523 }, + { grid_y: 121065, count: 3800, grid_x: 480487 }, + { grid_y: 121065, count: 3800, grid_x: 480488 }, + { grid_y: 121065, count: 3800, grid_x: 480489 }, + { grid_y: 121065, count: 11400, grid_x: 480490 }, + { grid_y: 121065, count: 7600, grid_x: 480491 }, + { grid_y: 121065, count: 3800, grid_x: 480492 }, + { grid_y: 121065, count: 7600, grid_x: 480499 }, + { grid_y: 121065, count: 3800, grid_x: 480500 }, + { grid_y: 121065, count: 7600, grid_x: 480501 }, + { grid_y: 121065, count: 3800, grid_x: 480509 }, + { grid_y: 121065, count: 3800, grid_x: 480512 }, + { grid_y: 121065, count: 3800, grid_x: 480516 }, + { grid_y: 121065, count: 3800, grid_x: 480527 }, + { grid_y: 121066, count: 3800, grid_x: 480488 }, + { grid_y: 121066, count: 7600, grid_x: 480489 }, + { grid_y: 121066, count: 3800, grid_x: 480490 }, + { grid_y: 121066, count: 11400, grid_x: 480491 }, + { grid_y: 121066, count: 7600, grid_x: 480492 }, + { grid_y: 121066, count: 3800, grid_x: 480496 }, + { grid_y: 121066, count: 7600, grid_x: 480498 }, + { grid_y: 121066, count: 3800, grid_x: 480500 }, + { grid_y: 121066, count: 7600, grid_x: 480501 }, + { grid_y: 121066, count: 3800, grid_x: 480505 }, + { grid_y: 121066, count: 3800, grid_x: 480509 }, + { grid_y: 121066, count: 3800, grid_x: 480511 }, + { grid_y: 121066, count: 3800, grid_x: 480512 }, + { grid_y: 121066, count: 3800, grid_x: 480514 }, + { grid_y: 121067, count: 15200, grid_x: 480491 }, + { grid_y: 121067, count: 3800, grid_x: 480493 }, + { grid_y: 121067, count: 3800, grid_x: 480494 }, + { grid_y: 121067, count: 7600, grid_x: 480495 }, + { grid_y: 121067, count: 7600, grid_x: 480496 }, + { grid_y: 121067, count: 7600, grid_x: 480497 }, + { grid_y: 121067, count: 7600, grid_x: 480498 }, + { grid_y: 121067, count: 3800, grid_x: 480499 }, + { grid_y: 121067, count: 11400, grid_x: 480500 }, + { grid_y: 121067, count: 3800, grid_x: 480501 }, + { grid_y: 121067, count: 3800, grid_x: 480503 }, + { grid_y: 121067, count: 3800, grid_x: 480509 }, + { grid_y: 121067, count: 3800, grid_x: 480513 }, + { grid_y: 121067, count: 3800, grid_x: 480515 }, + { grid_y: 121068, count: 7600, grid_x: 480488 }, + { grid_y: 121068, count: 7600, grid_x: 480489 }, + { grid_y: 121068, count: 11400, grid_x: 480490 }, + { grid_y: 121068, count: 3800, grid_x: 480491 }, + { grid_y: 121068, count: 7600, grid_x: 480493 }, + { grid_y: 121068, count: 3800, grid_x: 480494 }, + { grid_y: 121068, count: 3800, grid_x: 480495 }, + { grid_y: 121068, count: 41800, grid_x: 480499 }, + { grid_y: 121068, count: 19000, grid_x: 480500 }, + { grid_y: 121068, count: 3800, grid_x: 480501 }, + { grid_y: 121068, count: 3800, grid_x: 480502 }, + { grid_y: 121068, count: 3800, grid_x: 480504 }, + { grid_y: 121068, count: 3800, grid_x: 480509 }, + { grid_y: 121068, count: 3800, grid_x: 480515 }, + { grid_y: 121069, count: 3800, grid_x: 480489 }, + { grid_y: 121069, count: 3800, grid_x: 480491 }, + { grid_y: 121069, count: 7600, grid_x: 480492 }, + { grid_y: 121069, count: 7600, grid_x: 480493 }, + { grid_y: 121069, count: 3800, grid_x: 480494 }, + { grid_y: 121069, count: 3800, grid_x: 480495 }, + { grid_y: 121069, count: 7600, grid_x: 480499 }, + { grid_y: 121069, count: 3800, grid_x: 480502 }, + { grid_y: 121069, count: 3800, grid_x: 480509 }, + { grid_y: 121069, count: 3800, grid_x: 480513 }, + { grid_y: 121069, count: 3800, grid_x: 480515 }, + { grid_y: 121069, count: 3800, grid_x: 480517 }, + { grid_y: 121069, count: 7600, grid_x: 480524 }, + { grid_y: 121070, count: 3800, grid_x: 480490 }, + { grid_y: 121070, count: 11400, grid_x: 480491 }, + { grid_y: 121070, count: 3800, grid_x: 480492 }, + { grid_y: 121070, count: 3800, grid_x: 480497 }, + { grid_y: 121070, count: 3800, grid_x: 480501 }, + { grid_y: 121070, count: 7600, grid_x: 480510 }, + { grid_y: 121070, count: 19000, grid_x: 480513 }, + { grid_y: 121070, count: 3800, grid_x: 480514 }, + { grid_y: 121070, count: 3800, grid_x: 480515 }, + { grid_y: 121070, count: 11400, grid_x: 480516 }, + { grid_y: 121070, count: 7600, grid_x: 480517 }, + { grid_y: 121070, count: 3800, grid_x: 480518 }, + { grid_y: 121070, count: 3800, grid_x: 480519 }, + { grid_y: 121070, count: 7600, grid_x: 480533 }, + { grid_y: 121071, count: 11400, grid_x: 480491 }, + { grid_y: 121071, count: 7600, grid_x: 480492 }, + { grid_y: 121071, count: 15200, grid_x: 480493 }, + { grid_y: 121071, count: 7600, grid_x: 480494 }, + { grid_y: 121071, count: 3800, grid_x: 480495 }, + { grid_y: 121071, count: 3800, grid_x: 480497 }, + { grid_y: 121071, count: 3800, grid_x: 480502 }, + { grid_y: 121071, count: 3800, grid_x: 480503 }, + { grid_y: 121071, count: 3800, grid_x: 480510 }, + { grid_y: 121071, count: 11400, grid_x: 480513 }, + { grid_y: 121071, count: 7600, grid_x: 480515 }, + { grid_y: 121071, count: 7600, grid_x: 480516 }, + { grid_y: 121071, count: 7600, grid_x: 480517 }, + { grid_y: 121071, count: 3800, grid_x: 480519 }, + { grid_y: 121071, count: 3800, grid_x: 480520 }, + { grid_y: 121071, count: 3800, grid_x: 480523 }, + { grid_y: 121072, count: 15200, grid_x: 480492 }, + { grid_y: 121072, count: 11400, grid_x: 480493 }, + { grid_y: 121072, count: 3800, grid_x: 480494 }, + { grid_y: 121072, count: 3800, grid_x: 480496 }, + { grid_y: 121072, count: 3800, grid_x: 480500 }, + { grid_y: 121072, count: 7600, grid_x: 480501 }, + { grid_y: 121072, count: 3800, grid_x: 480508 }, + { grid_y: 121072, count: 7600, grid_x: 480514 }, + { grid_y: 121072, count: 3800, grid_x: 480515 }, + { grid_y: 121072, count: 3800, grid_x: 480517 }, + { grid_y: 121072, count: 3800, grid_x: 480518 }, + { grid_y: 121073, count: 7600, grid_x: 480491 }, + { grid_y: 121073, count: 7600, grid_x: 480492 }, + { grid_y: 121073, count: 3800, grid_x: 480494 }, + { grid_y: 121073, count: 3800, grid_x: 480497 }, + { grid_y: 121073, count: 11400, grid_x: 480501 }, + { grid_y: 121073, count: 7600, grid_x: 480502 }, + { grid_y: 121073, count: 3800, grid_x: 480503 }, + { grid_y: 121073, count: 3800, grid_x: 480504 }, + { grid_y: 121073, count: 3800, grid_x: 480511 }, + { grid_y: 121073, count: 3800, grid_x: 480512 }, + { grid_y: 121073, count: 3800, grid_x: 480516 }, + { grid_y: 121073, count: 3800, grid_x: 480517 }, + { grid_y: 121074, count: 3800, grid_x: 480459 }, + { grid_y: 121074, count: 3800, grid_x: 480491 }, + { grid_y: 121074, count: 3800, grid_x: 480492 }, + { grid_y: 121074, count: 3800, grid_x: 480493 }, + { grid_y: 121074, count: 3800, grid_x: 480494 }, + { grid_y: 121074, count: 7600, grid_x: 480497 }, + { grid_y: 121074, count: 3800, grid_x: 480498 }, + { grid_y: 121074, count: 3800, grid_x: 480499 }, + { grid_y: 121074, count: 7600, grid_x: 480501 }, + { grid_y: 121074, count: 15200, grid_x: 480502 }, + { grid_y: 121074, count: 3800, grid_x: 480503 }, + { grid_y: 121074, count: 3800, grid_x: 480507 }, + { grid_y: 121074, count: 7600, grid_x: 480517 }, + { grid_y: 121074, count: 3800, grid_x: 480520 }, + { grid_y: 121075, count: 3800, grid_x: 480493 }, + { grid_y: 121075, count: 3800, grid_x: 480495 }, + { grid_y: 121075, count: 3800, grid_x: 480496 }, + { grid_y: 121075, count: 3800, grid_x: 480497 }, + { grid_y: 121075, count: 7600, grid_x: 480498 }, + { grid_y: 121075, count: 7600, grid_x: 480499 }, + { grid_y: 121075, count: 7600, grid_x: 480500 }, + { grid_y: 121075, count: 7600, grid_x: 480501 }, + { grid_y: 121075, count: 7600, grid_x: 480502 }, + { grid_y: 121075, count: 7600, grid_x: 480503 }, + { grid_y: 121075, count: 3800, grid_x: 480504 }, + { grid_y: 121075, count: 7600, grid_x: 480506 }, + { grid_y: 121075, count: 3800, grid_x: 480511 }, + { grid_y: 121075, count: 3800, grid_x: 480517 }, + { grid_y: 121075, count: 3800, grid_x: 480518 }, + { grid_y: 121075, count: 3800, grid_x: 480519 }, + { grid_y: 121075, count: 7600, grid_x: 480520 }, + { grid_y: 121076, count: 3800, grid_x: 480491 }, + { grid_y: 121076, count: 7600, grid_x: 480498 }, + { grid_y: 121076, count: 7600, grid_x: 480499 }, + { grid_y: 121076, count: 3800, grid_x: 480501 }, + { grid_y: 121076, count: 3800, grid_x: 480502 }, + { grid_y: 121076, count: 15200, grid_x: 480503 }, + { grid_y: 121076, count: 3800, grid_x: 480509 }, + { grid_y: 121076, count: 3800, grid_x: 480515 }, + { grid_y: 121076, count: 3800, grid_x: 480516 }, + { grid_y: 121076, count: 3800, grid_x: 480521 }, + { grid_y: 121076, count: 3800, grid_x: 480523 }, + { grid_y: 121077, count: 3800, grid_x: 480475 }, + { grid_y: 121077, count: 3800, grid_x: 480496 }, + { grid_y: 121077, count: 7600, grid_x: 480498 }, + { grid_y: 121077, count: 7600, grid_x: 480499 }, + { grid_y: 121077, count: 7600, grid_x: 480500 }, + { grid_y: 121077, count: 3800, grid_x: 480501 }, + { grid_y: 121077, count: 3800, grid_x: 480503 }, + { grid_y: 121077, count: 7600, grid_x: 480506 }, + { grid_y: 121077, count: 3800, grid_x: 480509 }, + { grid_y: 121077, count: 3800, grid_x: 480511 }, + { grid_y: 121077, count: 3800, grid_x: 480517 }, + { grid_y: 121077, count: 3800, grid_x: 480518 }, + { grid_y: 121077, count: 3800, grid_x: 480531 }, + { grid_y: 121078, count: 3800, grid_x: 480462 }, + { grid_y: 121078, count: 3800, grid_x: 480474 }, + { grid_y: 121078, count: 3800, grid_x: 480479 }, + { grid_y: 121078, count: 3800, grid_x: 480485 }, + { grid_y: 121078, count: 3800, grid_x: 480496 }, + { grid_y: 121078, count: 7600, grid_x: 480497 }, + { grid_y: 121078, count: 3800, grid_x: 480499 }, + { grid_y: 121078, count: 7600, grid_x: 480501 }, + { grid_y: 121078, count: 3800, grid_x: 480502 }, + { grid_y: 121078, count: 3800, grid_x: 480507 }, + { grid_y: 121078, count: 7600, grid_x: 480509 }, + { grid_y: 121078, count: 15200, grid_x: 480510 }, + { grid_y: 121078, count: 3800, grid_x: 480512 }, + { grid_y: 121078, count: 3800, grid_x: 480529 }, + { grid_y: 121078, count: 3800, grid_x: 480530 }, + { grid_y: 121079, count: 3800, grid_x: 480462 }, + { grid_y: 121079, count: 3800, grid_x: 480478 }, + { grid_y: 121079, count: 3800, grid_x: 480497 }, + { grid_y: 121079, count: 3800, grid_x: 480499 }, + { grid_y: 121079, count: 3800, grid_x: 480504 }, + { grid_y: 121079, count: 3800, grid_x: 480511 }, + { grid_y: 121079, count: 3800, grid_x: 480532 }, + { grid_y: 121080, count: 3800, grid_x: 480479 }, + { grid_y: 121080, count: 3800, grid_x: 480491 }, + { grid_y: 121080, count: 3800, grid_x: 480492 }, + { grid_y: 121080, count: 3800, grid_x: 480493 }, + { grid_y: 121080, count: 7600, grid_x: 480494 }, + { grid_y: 121080, count: 3800, grid_x: 480495 }, + { grid_y: 121080, count: 3800, grid_x: 480499 }, + { grid_y: 121080, count: 3800, grid_x: 480500 }, + { grid_y: 121080, count: 3800, grid_x: 480510 }, + { grid_y: 121080, count: 3800, grid_x: 480520 }, + { grid_y: 121081, count: 11400, grid_x: 480462 }, + { grid_y: 121081, count: 3800, grid_x: 480492 }, + { grid_y: 121081, count: 3800, grid_x: 480493 }, + { grid_y: 121081, count: 3800, grid_x: 480494 }, + { grid_y: 121081, count: 11400, grid_x: 480495 }, + { grid_y: 121081, count: 3800, grid_x: 480518 }, + { grid_y: 121081, count: 3800, grid_x: 480522 }, + { grid_y: 121081, count: 3800, grid_x: 480523 }, + { grid_y: 121082, count: 3800, grid_x: 480490 }, + { grid_y: 121082, count: 3800, grid_x: 480494 }, + { grid_y: 121082, count: 3800, grid_x: 480507 }, + { grid_y: 121082, count: 3800, grid_x: 480510 }, + { grid_y: 121082, count: 3800, grid_x: 480519 }, + { grid_y: 121082, count: 3800, grid_x: 480520 }, + { grid_y: 121082, count: 3800, grid_x: 480521 }, + { grid_y: 121083, count: 3800, grid_x: 480511 }, + { grid_y: 121083, count: 7600, grid_x: 480513 }, + { grid_y: 121083, count: 3800, grid_x: 480514 }, + { grid_y: 121083, count: 3800, grid_x: 480515 }, + { grid_y: 121083, count: 3800, grid_x: 480516 }, + { grid_y: 121083, count: 3800, grid_x: 480520 }, + { grid_y: 121083, count: 3800, grid_x: 480522 }, + { grid_y: 121083, count: 3800, grid_x: 480523 }, + { grid_y: 121083, count: 7600, grid_x: 480524 }, + { grid_y: 121083, count: 3800, grid_x: 480525 }, + { grid_y: 121084, count: 3800, grid_x: 480485 }, + { grid_y: 121084, count: 3800, grid_x: 480486 }, + { grid_y: 121084, count: 3800, grid_x: 480487 }, + { grid_y: 121084, count: 3800, grid_x: 480494 }, + { grid_y: 121084, count: 3800, grid_x: 480495 }, + { grid_y: 121084, count: 3800, grid_x: 480497 }, + { grid_y: 121084, count: 3800, grid_x: 480500 }, + { grid_y: 121084, count: 3800, grid_x: 480512 }, + { grid_y: 121084, count: 22800, grid_x: 480513 }, + { grid_y: 121084, count: 7600, grid_x: 480514 }, + { grid_y: 121084, count: 3800, grid_x: 480515 }, + { grid_y: 121084, count: 3800, grid_x: 480520 }, + { grid_y: 121084, count: 3800, grid_x: 480521 }, + { grid_y: 121084, count: 3800, grid_x: 480522 }, + { grid_y: 121084, count: 3800, grid_x: 480523 }, + { grid_y: 121084, count: 3800, grid_x: 480531 }, + { grid_y: 121085, count: 3800, grid_x: 480499 }, + { grid_y: 121085, count: 7600, grid_x: 480500 }, + { grid_y: 121085, count: 3800, grid_x: 480501 }, + { grid_y: 121085, count: 3800, grid_x: 480504 }, + { grid_y: 121085, count: 3800, grid_x: 480506 }, + { grid_y: 121085, count: 7600, grid_x: 480513 }, + { grid_y: 121085, count: 11400, grid_x: 480514 }, + { grid_y: 121085, count: 3800, grid_x: 480515 }, + { grid_y: 121085, count: 3800, grid_x: 480517 }, + { grid_y: 121085, count: 3800, grid_x: 480518 }, + { grid_y: 121085, count: 3800, grid_x: 480520 }, + { grid_y: 121085, count: 3800, grid_x: 480527 }, + { grid_y: 121085, count: 3800, grid_x: 480532 }, + { grid_y: 121086, count: 3800, grid_x: 480483 }, + { grid_y: 121086, count: 3800, grid_x: 480490 }, + { grid_y: 121086, count: 7600, grid_x: 480494 }, + { grid_y: 121086, count: 3800, grid_x: 480497 }, + { grid_y: 121086, count: 7600, grid_x: 480498 }, + { grid_y: 121086, count: 3800, grid_x: 480499 }, + { grid_y: 121086, count: 7600, grid_x: 480500 }, + { grid_y: 121086, count: 3800, grid_x: 480507 }, + { grid_y: 121086, count: 3800, grid_x: 480511 }, + { grid_y: 121086, count: 7600, grid_x: 480512 }, + { grid_y: 121086, count: 7600, grid_x: 480516 }, + { grid_y: 121086, count: 3800, grid_x: 480517 }, + { grid_y: 121086, count: 7600, grid_x: 480518 }, + { grid_y: 121086, count: 3800, grid_x: 480520 }, + { grid_y: 121086, count: 11400, grid_x: 480521 }, + { grid_y: 121086, count: 3800, grid_x: 480523 }, + { grid_y: 121086, count: 3800, grid_x: 480524 }, + { grid_y: 121086, count: 3800, grid_x: 480527 }, + { grid_y: 121086, count: 7600, grid_x: 480528 }, + { grid_y: 121086, count: 3800, grid_x: 480529 }, + { grid_y: 121086, count: 3800, grid_x: 480531 }, + { grid_y: 121087, count: 7600, grid_x: 480460 }, + { grid_y: 121087, count: 3800, grid_x: 480463 }, + { grid_y: 121087, count: 3800, grid_x: 480472 }, + { grid_y: 121087, count: 3800, grid_x: 480489 }, + { grid_y: 121087, count: 3800, grid_x: 480494 }, + { grid_y: 121087, count: 3800, grid_x: 480495 }, + { grid_y: 121087, count: 7600, grid_x: 480501 }, + { grid_y: 121087, count: 15200, grid_x: 480502 }, + { grid_y: 121087, count: 11400, grid_x: 480503 }, + { grid_y: 121087, count: 7600, grid_x: 480504 }, + { grid_y: 121087, count: 7600, grid_x: 480508 }, + { grid_y: 121087, count: 3800, grid_x: 480518 }, + { grid_y: 121087, count: 3800, grid_x: 480519 }, + { grid_y: 121087, count: 3800, grid_x: 480527 }, + { grid_y: 121087, count: 3800, grid_x: 480528 }, + { grid_y: 121087, count: 3800, grid_x: 480529 }, + { grid_y: 121087, count: 7600, grid_x: 480533 }, + { grid_y: 121088, count: 3800, grid_x: 480460 }, + { grid_y: 121088, count: 3800, grid_x: 480478 }, + { grid_y: 121088, count: 7600, grid_x: 480479 }, + { grid_y: 121088, count: 3800, grid_x: 480483 }, + { grid_y: 121088, count: 3800, grid_x: 480487 }, + { grid_y: 121088, count: 7600, grid_x: 480491 }, + { grid_y: 121088, count: 3800, grid_x: 480493 }, + { grid_y: 121088, count: 3800, grid_x: 480494 }, + { grid_y: 121088, count: 7600, grid_x: 480496 }, + { grid_y: 121088, count: 3800, grid_x: 480497 }, + { grid_y: 121088, count: 3800, grid_x: 480498 }, + { grid_y: 121088, count: 3800, grid_x: 480502 }, + { grid_y: 121088, count: 7600, grid_x: 480503 }, + { grid_y: 121088, count: 3800, grid_x: 480504 }, + { grid_y: 121088, count: 3800, grid_x: 480505 }, + { grid_y: 121088, count: 7600, grid_x: 480506 }, + { grid_y: 121088, count: 3800, grid_x: 480507 }, + { grid_y: 121088, count: 7600, grid_x: 480508 }, + { grid_y: 121088, count: 7600, grid_x: 480510 }, + { grid_y: 121088, count: 3800, grid_x: 480511 }, + { grid_y: 121088, count: 7600, grid_x: 480512 }, + { grid_y: 121088, count: 7600, grid_x: 480520 }, + { grid_y: 121088, count: 3800, grid_x: 480529 }, + { grid_y: 121089, count: 3800, grid_x: 480462 }, + { grid_y: 121089, count: 3800, grid_x: 480470 }, + { grid_y: 121089, count: 3800, grid_x: 480472 }, + { grid_y: 121089, count: 3800, grid_x: 480474 }, + { grid_y: 121089, count: 3800, grid_x: 480475 }, + { grid_y: 121089, count: 3800, grid_x: 480476 }, + { grid_y: 121089, count: 7600, grid_x: 480477 }, + { grid_y: 121089, count: 3800, grid_x: 480480 }, + { grid_y: 121089, count: 3800, grid_x: 480481 }, + { grid_y: 121089, count: 7600, grid_x: 480482 }, + { grid_y: 121089, count: 3800, grid_x: 480486 }, + { grid_y: 121089, count: 3800, grid_x: 480489 }, + { grid_y: 121089, count: 3800, grid_x: 480491 }, + { grid_y: 121089, count: 7600, grid_x: 480493 }, + { grid_y: 121089, count: 11400, grid_x: 480498 }, + { grid_y: 121089, count: 3800, grid_x: 480501 }, + { grid_y: 121089, count: 7600, grid_x: 480502 }, + { grid_y: 121089, count: 3800, grid_x: 480503 }, + { grid_y: 121089, count: 3800, grid_x: 480504 }, + { grid_y: 121089, count: 3800, grid_x: 480505 }, + { grid_y: 121089, count: 7600, grid_x: 480506 }, + { grid_y: 121089, count: 3800, grid_x: 480508 }, + { grid_y: 121089, count: 7600, grid_x: 480512 }, + { grid_y: 121089, count: 3800, grid_x: 480514 }, + { grid_y: 121089, count: 3800, grid_x: 480521 }, + { grid_y: 121089, count: 3800, grid_x: 480530 }, + { grid_y: 121090, count: 3800, grid_x: 480461 }, + { grid_y: 121090, count: 3800, grid_x: 480467 }, + { grid_y: 121090, count: 3800, grid_x: 480470 }, + { grid_y: 121090, count: 3800, grid_x: 480474 }, + { grid_y: 121090, count: 3800, grid_x: 480475 }, + { grid_y: 121090, count: 7600, grid_x: 480480 }, + { grid_y: 121090, count: 3800, grid_x: 480484 }, + { grid_y: 121090, count: 3800, grid_x: 480487 }, + { grid_y: 121090, count: 3800, grid_x: 480495 }, + { grid_y: 121090, count: 3800, grid_x: 480498 }, + { grid_y: 121090, count: 7600, grid_x: 480499 }, + { grid_y: 121090, count: 3800, grid_x: 480500 }, + { grid_y: 121090, count: 45600, grid_x: 480501 }, + { grid_y: 121090, count: 34200, grid_x: 480502 }, + { grid_y: 121090, count: 15200, grid_x: 480503 }, + { grid_y: 121090, count: 7600, grid_x: 480504 }, + { grid_y: 121090, count: 7600, grid_x: 480505 }, + { grid_y: 121090, count: 3800, grid_x: 480506 }, + { grid_y: 121090, count: 3800, grid_x: 480508 }, + { grid_y: 121090, count: 3800, grid_x: 480509 }, + { grid_y: 121090, count: 3800, grid_x: 480510 }, + { grid_y: 121090, count: 3800, grid_x: 480511 }, + { grid_y: 121090, count: 3800, grid_x: 480512 }, + { grid_y: 121090, count: 3800, grid_x: 480521 }, + { grid_y: 121090, count: 3800, grid_x: 480522 }, + { grid_y: 121090, count: 3800, grid_x: 480523 }, + { grid_y: 121090, count: 3800, grid_x: 480524 }, + { grid_y: 121090, count: 7600, grid_x: 480525 }, + { grid_y: 121090, count: 3800, grid_x: 480527 }, + { grid_y: 121091, count: 3800, grid_x: 480461 }, + { grid_y: 121091, count: 3800, grid_x: 480467 }, + { grid_y: 121091, count: 7600, grid_x: 480472 }, + { grid_y: 121091, count: 3800, grid_x: 480481 }, + { grid_y: 121091, count: 3800, grid_x: 480486 }, + { grid_y: 121091, count: 7600, grid_x: 480491 }, + { grid_y: 121091, count: 7600, grid_x: 480493 }, + { grid_y: 121091, count: 3800, grid_x: 480494 }, + { grid_y: 121091, count: 15200, grid_x: 480495 }, + { grid_y: 121091, count: 7600, grid_x: 480496 }, + { grid_y: 121091, count: 11400, grid_x: 480498 }, + { grid_y: 121091, count: 11400, grid_x: 480500 }, + { grid_y: 121091, count: 3800, grid_x: 480501 }, + { grid_y: 121091, count: 11400, grid_x: 480502 }, + { grid_y: 121091, count: 7600, grid_x: 480503 }, + { grid_y: 121091, count: 7600, grid_x: 480504 }, + { grid_y: 121091, count: 3800, grid_x: 480508 }, + { grid_y: 121091, count: 3800, grid_x: 480509 }, + { grid_y: 121091, count: 3800, grid_x: 480520 }, + { grid_y: 121091, count: 7600, grid_x: 480521 }, + { grid_y: 121091, count: 7600, grid_x: 480522 }, + { grid_y: 121091, count: 26600, grid_x: 480523 }, + { grid_y: 121091, count: 7600, grid_x: 480524 }, + { grid_y: 121091, count: 7600, grid_x: 480525 }, + { grid_y: 121091, count: 15200, grid_x: 480526 }, + { grid_y: 121091, count: 3800, grid_x: 480527 }, + { grid_y: 121091, count: 3800, grid_x: 480528 }, + { grid_y: 121091, count: 3800, grid_x: 480532 }, + { grid_y: 121091, count: 3800, grid_x: 480533 }, + { grid_y: 121092, count: 7600, grid_x: 480460 }, + { grid_y: 121092, count: 3800, grid_x: 480465 }, + { grid_y: 121092, count: 7600, grid_x: 480466 }, + { grid_y: 121092, count: 3800, grid_x: 480467 }, + { grid_y: 121092, count: 3800, grid_x: 480468 }, + { grid_y: 121092, count: 3800, grid_x: 480469 }, + { grid_y: 121092, count: 3800, grid_x: 480474 }, + { grid_y: 121092, count: 7600, grid_x: 480482 }, + { grid_y: 121092, count: 3800, grid_x: 480491 }, + { grid_y: 121092, count: 3800, grid_x: 480492 }, + { grid_y: 121092, count: 3800, grid_x: 480493 }, + { grid_y: 121092, count: 7600, grid_x: 480494 }, + { grid_y: 121092, count: 11400, grid_x: 480495 }, + { grid_y: 121092, count: 3800, grid_x: 480496 }, + { grid_y: 121092, count: 15200, grid_x: 480498 }, + { grid_y: 121092, count: 7600, grid_x: 480499 }, + { grid_y: 121092, count: 3800, grid_x: 480501 }, + { grid_y: 121092, count: 7600, grid_x: 480502 }, + { grid_y: 121092, count: 3800, grid_x: 480503 }, + { grid_y: 121092, count: 3800, grid_x: 480504 }, + { grid_y: 121092, count: 7600, grid_x: 480507 }, + { grid_y: 121092, count: 3800, grid_x: 480508 }, + { grid_y: 121092, count: 3800, grid_x: 480511 }, + { grid_y: 121092, count: 3800, grid_x: 480512 }, + { grid_y: 121092, count: 3800, grid_x: 480516 }, + { grid_y: 121092, count: 7600, grid_x: 480523 }, + { grid_y: 121092, count: 7600, grid_x: 480524 }, + { grid_y: 121092, count: 7600, grid_x: 480525 }, + { grid_y: 121092, count: 7600, grid_x: 480526 }, + { grid_y: 121092, count: 3800, grid_x: 480532 }, + { grid_y: 121092, count: 3800, grid_x: 480533 }, + { grid_y: 121093, count: 3800, grid_x: 480463 }, + { grid_y: 121093, count: 7600, grid_x: 480466 }, + { grid_y: 121093, count: 3800, grid_x: 480468 }, + { grid_y: 121093, count: 3800, grid_x: 480493 }, + { grid_y: 121093, count: 3800, grid_x: 480494 }, + { grid_y: 121093, count: 3800, grid_x: 480496 }, + { grid_y: 121093, count: 3800, grid_x: 480498 }, + { grid_y: 121093, count: 3800, grid_x: 480499 }, + { grid_y: 121093, count: 3800, grid_x: 480502 }, + { grid_y: 121093, count: 3800, grid_x: 480503 }, + { grid_y: 121093, count: 3800, grid_x: 480504 }, + { grid_y: 121093, count: 3800, grid_x: 480507 }, + { grid_y: 121093, count: 3800, grid_x: 480508 }, + { grid_y: 121093, count: 3800, grid_x: 480509 }, + { grid_y: 121093, count: 3800, grid_x: 480512 }, + { grid_y: 121093, count: 3800, grid_x: 480514 }, + { grid_y: 121093, count: 3800, grid_x: 480520 }, + { grid_y: 121093, count: 3800, grid_x: 480521 }, + { grid_y: 121093, count: 3800, grid_x: 480523 }, + { grid_y: 121093, count: 3800, grid_x: 480524 }, + { grid_y: 121093, count: 3800, grid_x: 480526 }, + { grid_y: 121093, count: 3800, grid_x: 480532 }, + { grid_y: 121093, count: 3800, grid_x: 480533 }, + { grid_y: 121094, count: 3800, grid_x: 480467 }, + { grid_y: 121094, count: 3800, grid_x: 480491 }, + { grid_y: 121094, count: 3800, grid_x: 480496 }, + { grid_y: 121094, count: 3800, grid_x: 480497 }, + { grid_y: 121094, count: 7600, grid_x: 480499 }, + { grid_y: 121094, count: 3800, grid_x: 480503 }, + { grid_y: 121094, count: 7600, grid_x: 480509 }, + { grid_y: 121094, count: 3800, grid_x: 480514 }, + { grid_y: 121094, count: 3800, grid_x: 480519 }, + { grid_y: 121094, count: 3800, grid_x: 480521 }, + { grid_y: 121094, count: 7600, grid_x: 480532 }, + { grid_y: 121095, count: 3800, grid_x: 480462 }, + { grid_y: 121095, count: 3800, grid_x: 480467 }, + { grid_y: 121095, count: 3800, grid_x: 480472 }, + { grid_y: 121095, count: 3800, grid_x: 480473 }, + { grid_y: 121095, count: 3800, grid_x: 480476 }, + { grid_y: 121095, count: 3800, grid_x: 480480 }, + { grid_y: 121095, count: 3800, grid_x: 480497 }, + { grid_y: 121095, count: 3800, grid_x: 480498 }, + { grid_y: 121095, count: 3800, grid_x: 480501 }, + { grid_y: 121095, count: 3800, grid_x: 480515 }, + { grid_y: 121095, count: 3800, grid_x: 480520 }, + { grid_y: 121095, count: 3800, grid_x: 480522 }, + { grid_y: 121095, count: 3800, grid_x: 480530 }, + { grid_y: 121095, count: 3800, grid_x: 480531 }, + { grid_y: 121096, count: 3800, grid_x: 480465 }, + { grid_y: 121096, count: 3800, grid_x: 480483 }, + { grid_y: 121096, count: 7600, grid_x: 480485 }, + { grid_y: 121096, count: 3800, grid_x: 480489 }, + { grid_y: 121096, count: 3800, grid_x: 480491 }, + { grid_y: 121096, count: 3800, grid_x: 480494 }, + { grid_y: 121096, count: 7600, grid_x: 480497 }, + { grid_y: 121096, count: 3800, grid_x: 480498 }, + { grid_y: 121096, count: 3800, grid_x: 480499 }, + { grid_y: 121096, count: 3800, grid_x: 480500 }, + { grid_y: 121096, count: 7600, grid_x: 480502 }, + { grid_y: 121096, count: 7600, grid_x: 480503 }, + { grid_y: 121096, count: 3800, grid_x: 480504 }, + { grid_y: 121096, count: 3800, grid_x: 480505 }, + { grid_y: 121096, count: 3800, grid_x: 480507 }, + { grid_y: 121096, count: 3800, grid_x: 480510 }, + { grid_y: 121096, count: 3800, grid_x: 480511 }, + { grid_y: 121096, count: 3800, grid_x: 480512 }, + { grid_y: 121096, count: 7600, grid_x: 480515 }, + { grid_y: 121096, count: 3800, grid_x: 480517 }, + { grid_y: 121096, count: 7600, grid_x: 480520 }, + { grid_y: 121096, count: 3800, grid_x: 480525 }, + { grid_y: 121096, count: 3800, grid_x: 480527 }, + { grid_y: 121096, count: 3800, grid_x: 480529 }, + { grid_y: 121096, count: 3800, grid_x: 480531 }, + { grid_y: 121097, count: 3800, grid_x: 480465 }, + { grid_y: 121097, count: 3800, grid_x: 480472 }, + { grid_y: 121097, count: 3800, grid_x: 480482 }, + { grid_y: 121097, count: 11400, grid_x: 480483 }, + { grid_y: 121097, count: 3800, grid_x: 480484 }, + { grid_y: 121097, count: 3800, grid_x: 480485 }, + { grid_y: 121097, count: 3800, grid_x: 480486 }, + { grid_y: 121097, count: 11400, grid_x: 480487 }, + { grid_y: 121097, count: 7600, grid_x: 480488 }, + { grid_y: 121097, count: 7600, grid_x: 480489 }, + { grid_y: 121097, count: 7600, grid_x: 480491 }, + { grid_y: 121097, count: 11400, grid_x: 480492 }, + { grid_y: 121097, count: 3800, grid_x: 480493 }, + { grid_y: 121097, count: 3800, grid_x: 480494 }, + { grid_y: 121097, count: 7600, grid_x: 480495 }, + { grid_y: 121097, count: 3800, grid_x: 480497 }, + { grid_y: 121097, count: 7600, grid_x: 480499 }, + { grid_y: 121097, count: 3800, grid_x: 480501 }, + { grid_y: 121097, count: 3800, grid_x: 480506 }, + { grid_y: 121097, count: 3800, grid_x: 480509 }, + { grid_y: 121097, count: 7600, grid_x: 480513 }, + { grid_y: 121097, count: 3800, grid_x: 480515 }, + { grid_y: 121097, count: 7600, grid_x: 480520 }, + { grid_y: 121097, count: 3800, grid_x: 480522 }, + { grid_y: 121097, count: 3800, grid_x: 480531 }, + { grid_y: 121097, count: 7600, grid_x: 480532 }, + { grid_y: 121097, count: 7600, grid_x: 480533 }, + { grid_y: 121098, count: 7600, grid_x: 480464 }, + { grid_y: 121098, count: 3800, grid_x: 480475 }, + { grid_y: 121098, count: 7600, grid_x: 480484 }, + { grid_y: 121098, count: 11400, grid_x: 480487 }, + { grid_y: 121098, count: 11400, grid_x: 480489 }, + { grid_y: 121098, count: 3800, grid_x: 480497 }, + { grid_y: 121098, count: 7600, grid_x: 480499 }, + { grid_y: 121098, count: 15200, grid_x: 480501 }, + { grid_y: 121098, count: 3800, grid_x: 480502 }, + { grid_y: 121098, count: 3800, grid_x: 480504 }, + { grid_y: 121098, count: 3800, grid_x: 480509 }, + { grid_y: 121098, count: 3800, grid_x: 480519 }, + { grid_y: 121098, count: 3800, grid_x: 480521 }, + { grid_y: 121098, count: 7600, grid_x: 480523 }, + { grid_y: 121098, count: 3800, grid_x: 480524 }, + { grid_y: 121098, count: 3800, grid_x: 480526 }, + { grid_y: 121098, count: 3800, grid_x: 480529 }, + { grid_y: 121098, count: 3800, grid_x: 480532 }, + { grid_y: 121098, count: 7600, grid_x: 480533 }, + { grid_y: 121099, count: 7600, grid_x: 480461 }, + { grid_y: 121099, count: 3800, grid_x: 480464 }, + { grid_y: 121099, count: 3800, grid_x: 480469 }, + { grid_y: 121099, count: 7600, grid_x: 480470 }, + { grid_y: 121099, count: 3800, grid_x: 480477 }, + { grid_y: 121099, count: 3800, grid_x: 480481 }, + { grid_y: 121099, count: 3800, grid_x: 480482 }, + { grid_y: 121099, count: 7600, grid_x: 480485 }, + { grid_y: 121099, count: 7600, grid_x: 480486 }, + { grid_y: 121099, count: 19000, grid_x: 480487 }, + { grid_y: 121099, count: 7600, grid_x: 480488 }, + { grid_y: 121099, count: 3800, grid_x: 480497 }, + { grid_y: 121099, count: 3800, grid_x: 480499 }, + { grid_y: 121099, count: 7600, grid_x: 480500 }, + { grid_y: 121099, count: 19000, grid_x: 480501 }, + { grid_y: 121099, count: 7600, grid_x: 480502 }, + { grid_y: 121099, count: 3800, grid_x: 480504 }, + { grid_y: 121099, count: 7600, grid_x: 480505 }, + { grid_y: 121099, count: 3800, grid_x: 480519 }, + { grid_y: 121099, count: 3800, grid_x: 480520 }, + { grid_y: 121099, count: 3800, grid_x: 480528 }, + { grid_y: 121099, count: 7600, grid_x: 480532 }, + { grid_y: 121100, count: 3800, grid_x: 480461 }, + { grid_y: 121100, count: 3800, grid_x: 480462 }, + { grid_y: 121100, count: 3800, grid_x: 480465 }, + { grid_y: 121100, count: 3800, grid_x: 480480 }, + { grid_y: 121100, count: 15200, grid_x: 480481 }, + { grid_y: 121100, count: 3800, grid_x: 480484 }, + { grid_y: 121100, count: 7600, grid_x: 480487 }, + { grid_y: 121100, count: 11400, grid_x: 480488 }, + { grid_y: 121100, count: 7600, grid_x: 480489 }, + { grid_y: 121100, count: 3800, grid_x: 480490 }, + { grid_y: 121100, count: 3800, grid_x: 480497 }, + { grid_y: 121100, count: 7600, grid_x: 480502 }, + { grid_y: 121100, count: 7600, grid_x: 480504 }, + { grid_y: 121100, count: 7600, grid_x: 480505 }, + { grid_y: 121100, count: 3800, grid_x: 480508 }, + { grid_y: 121100, count: 3800, grid_x: 480523 }, + { grid_y: 121100, count: 3800, grid_x: 480528 }, + { grid_y: 121100, count: 3800, grid_x: 480529 }, + { grid_y: 121100, count: 7600, grid_x: 480530 }, + { grid_y: 121100, count: 3800, grid_x: 480531 }, + { grid_y: 121100, count: 7600, grid_x: 480532 }, + { grid_y: 121100, count: 7600, grid_x: 480533 }, + { grid_y: 121101, count: 3800, grid_x: 480459 }, + { grid_y: 121101, count: 3800, grid_x: 480462 }, + { grid_y: 121101, count: 3800, grid_x: 480475 }, + { grid_y: 121101, count: 7600, grid_x: 480482 }, + { grid_y: 121101, count: 7600, grid_x: 480488 }, + { grid_y: 121101, count: 7600, grid_x: 480489 }, + { grid_y: 121101, count: 3800, grid_x: 480492 }, + { grid_y: 121101, count: 3800, grid_x: 480497 }, + { grid_y: 121101, count: 3800, grid_x: 480498 }, + { grid_y: 121101, count: 3800, grid_x: 480501 }, + { grid_y: 121101, count: 7600, grid_x: 480504 }, + { grid_y: 121101, count: 11400, grid_x: 480505 }, + { grid_y: 121101, count: 3800, grid_x: 480510 }, + { grid_y: 121101, count: 3800, grid_x: 480517 }, + { grid_y: 121101, count: 3800, grid_x: 480519 }, + { grid_y: 121101, count: 7600, grid_x: 480520 }, + { grid_y: 121101, count: 3800, grid_x: 480522 }, + { grid_y: 121101, count: 3800, grid_x: 480527 }, + { grid_y: 121101, count: 7600, grid_x: 480528 }, + { grid_y: 121101, count: 7600, grid_x: 480529 }, + { grid_y: 121101, count: 7600, grid_x: 480530 }, + { grid_y: 121101, count: 7600, grid_x: 480531 }, + { grid_y: 121101, count: 11400, grid_x: 480532 }, + { grid_y: 121101, count: 11400, grid_x: 480533 }, + { grid_y: 121102, count: 3800, grid_x: 480466 }, + { grid_y: 121102, count: 3800, grid_x: 480468 }, + { grid_y: 121102, count: 3800, grid_x: 480479 }, + { grid_y: 121102, count: 3800, grid_x: 480480 }, + { grid_y: 121102, count: 3800, grid_x: 480481 }, + { grid_y: 121102, count: 3800, grid_x: 480486 }, + { grid_y: 121102, count: 3800, grid_x: 480487 }, + { grid_y: 121102, count: 3800, grid_x: 480488 }, + { grid_y: 121102, count: 3800, grid_x: 480489 }, + { grid_y: 121102, count: 3800, grid_x: 480490 }, + { grid_y: 121102, count: 3800, grid_x: 480492 }, + { grid_y: 121102, count: 7600, grid_x: 480493 }, + { grid_y: 121102, count: 3800, grid_x: 480497 }, + { grid_y: 121102, count: 3800, grid_x: 480499 }, + { grid_y: 121102, count: 3800, grid_x: 480501 }, + { grid_y: 121102, count: 3800, grid_x: 480503 }, + { grid_y: 121102, count: 7600, grid_x: 480504 }, + { grid_y: 121102, count: 11400, grid_x: 480505 }, + { grid_y: 121102, count: 7600, grid_x: 480506 }, + { grid_y: 121102, count: 3800, grid_x: 480514 }, + { grid_y: 121102, count: 3800, grid_x: 480518 }, + { grid_y: 121102, count: 7600, grid_x: 480519 }, + { grid_y: 121102, count: 3800, grid_x: 480525 }, + { grid_y: 121102, count: 7600, grid_x: 480527 }, + { grid_y: 121102, count: 7600, grid_x: 480528 }, + { grid_y: 121102, count: 7600, grid_x: 480529 }, + { grid_y: 121102, count: 15200, grid_x: 480530 }, + { grid_y: 121102, count: 3800, grid_x: 480531 }, + { grid_y: 121102, count: 3800, grid_x: 480532 }, + { grid_y: 121102, count: 7600, grid_x: 480533 }, + { grid_y: 121103, count: 3800, grid_x: 480459 }, + { grid_y: 121103, count: 3800, grid_x: 480460 }, + { grid_y: 121103, count: 7600, grid_x: 480471 }, + { grid_y: 121103, count: 3800, grid_x: 480472 }, + { grid_y: 121103, count: 3800, grid_x: 480481 }, + { grid_y: 121103, count: 3800, grid_x: 480482 }, + { grid_y: 121103, count: 3800, grid_x: 480484 }, + { grid_y: 121103, count: 3800, grid_x: 480485 }, + { grid_y: 121103, count: 11400, grid_x: 480488 }, + { grid_y: 121103, count: 15200, grid_x: 480489 }, + { grid_y: 121103, count: 7600, grid_x: 480495 }, + { grid_y: 121103, count: 7600, grid_x: 480496 }, + { grid_y: 121103, count: 3800, grid_x: 480497 }, + { grid_y: 121103, count: 3800, grid_x: 480501 }, + { grid_y: 121103, count: 3800, grid_x: 480503 }, + { grid_y: 121103, count: 7600, grid_x: 480505 }, + { grid_y: 121103, count: 3800, grid_x: 480506 }, + { grid_y: 121103, count: 3800, grid_x: 480507 }, + { grid_y: 121103, count: 3800, grid_x: 480509 }, + { grid_y: 121103, count: 3800, grid_x: 480510 }, + { grid_y: 121103, count: 3800, grid_x: 480514 }, + { grid_y: 121103, count: 3800, grid_x: 480517 }, + { grid_y: 121103, count: 3800, grid_x: 480519 }, + { grid_y: 121103, count: 3800, grid_x: 480522 }, + { grid_y: 121103, count: 3800, grid_x: 480525 }, + { grid_y: 121103, count: 3800, grid_x: 480528 }, + { grid_y: 121103, count: 3800, grid_x: 480529 }, + { grid_y: 121103, count: 3800, grid_x: 480530 }, + { grid_y: 121103, count: 3800, grid_x: 480533 }, + { grid_y: 121104, count: 3800, grid_x: 480460 }, + { grid_y: 121104, count: 3800, grid_x: 480461 }, + { grid_y: 121104, count: 3800, grid_x: 480463 }, + { grid_y: 121104, count: 3800, grid_x: 480466 }, + { grid_y: 121104, count: 3800, grid_x: 480477 }, + { grid_y: 121104, count: 7600, grid_x: 480478 }, + { grid_y: 121104, count: 7600, grid_x: 480479 }, + { grid_y: 121104, count: 3800, grid_x: 480480 }, + { grid_y: 121104, count: 7600, grid_x: 480481 }, + { grid_y: 121104, count: 7600, grid_x: 480482 }, + { grid_y: 121104, count: 3800, grid_x: 480483 }, + { grid_y: 121104, count: 3800, grid_x: 480487 }, + { grid_y: 121104, count: 11400, grid_x: 480488 }, + { grid_y: 121104, count: 7600, grid_x: 480489 }, + { grid_y: 121104, count: 15200, grid_x: 480490 }, + { grid_y: 121104, count: 3800, grid_x: 480491 }, + { grid_y: 121104, count: 3800, grid_x: 480494 }, + { grid_y: 121104, count: 7600, grid_x: 480495 }, + { grid_y: 121104, count: 7600, grid_x: 480496 }, + { grid_y: 121104, count: 7600, grid_x: 480497 }, + { grid_y: 121104, count: 3800, grid_x: 480499 }, + { grid_y: 121104, count: 3800, grid_x: 480500 }, + { grid_y: 121104, count: 3800, grid_x: 480506 }, + { grid_y: 121104, count: 3800, grid_x: 480513 }, + { grid_y: 121104, count: 3800, grid_x: 480515 }, + { grid_y: 121104, count: 7600, grid_x: 480516 }, + { grid_y: 121104, count: 7600, grid_x: 480517 }, + { grid_y: 121104, count: 3800, grid_x: 480519 }, + { grid_y: 121104, count: 7600, grid_x: 480520 }, + { grid_y: 121104, count: 3800, grid_x: 480524 }, + { grid_y: 121104, count: 7600, grid_x: 480525 }, + { grid_y: 121104, count: 7600, grid_x: 480526 }, + { grid_y: 121104, count: 3800, grid_x: 480527 }, + { grid_y: 121104, count: 3800, grid_x: 480528 }, + { grid_y: 121104, count: 7600, grid_x: 480530 }, + { grid_y: 121104, count: 7600, grid_x: 480531 }, + { grid_y: 121105, count: 3800, grid_x: 480460 }, + { grid_y: 121105, count: 7600, grid_x: 480462 }, + { grid_y: 121105, count: 3800, grid_x: 480463 }, + { grid_y: 121105, count: 3800, grid_x: 480464 }, + { grid_y: 121105, count: 3800, grid_x: 480467 }, + { grid_y: 121105, count: 3800, grid_x: 480468 }, + { grid_y: 121105, count: 3800, grid_x: 480469 }, + { grid_y: 121105, count: 7600, grid_x: 480470 }, + { grid_y: 121105, count: 7600, grid_x: 480472 }, + { grid_y: 121105, count: 3800, grid_x: 480473 }, + { grid_y: 121105, count: 3800, grid_x: 480476 }, + { grid_y: 121105, count: 7600, grid_x: 480477 }, + { grid_y: 121105, count: 7600, grid_x: 480480 }, + { grid_y: 121105, count: 3800, grid_x: 480481 }, + { grid_y: 121105, count: 7600, grid_x: 480482 }, + { grid_y: 121105, count: 7600, grid_x: 480483 }, + { grid_y: 121105, count: 3800, grid_x: 480485 }, + { grid_y: 121105, count: 7600, grid_x: 480487 }, + { grid_y: 121105, count: 3800, grid_x: 480488 }, + { grid_y: 121105, count: 22800, grid_x: 480489 }, + { grid_y: 121105, count: 15200, grid_x: 480490 }, + { grid_y: 121105, count: 11400, grid_x: 480492 }, + { grid_y: 121105, count: 3800, grid_x: 480493 }, + { grid_y: 121105, count: 3800, grid_x: 480494 }, + { grid_y: 121105, count: 3800, grid_x: 480495 }, + { grid_y: 121105, count: 3800, grid_x: 480496 }, + { grid_y: 121105, count: 7600, grid_x: 480497 }, + { grid_y: 121105, count: 3800, grid_x: 480500 }, + { grid_y: 121105, count: 3800, grid_x: 480501 }, + { grid_y: 121105, count: 3800, grid_x: 480509 }, + { grid_y: 121105, count: 3800, grid_x: 480515 }, + { grid_y: 121105, count: 3800, grid_x: 480517 }, + { grid_y: 121105, count: 3800, grid_x: 480518 }, + { grid_y: 121105, count: 3800, grid_x: 480519 }, + { grid_y: 121105, count: 3800, grid_x: 480520 }, + { grid_y: 121105, count: 3800, grid_x: 480521 }, + { grid_y: 121105, count: 3800, grid_x: 480522 }, + { grid_y: 121105, count: 11400, grid_x: 480526 }, + { grid_y: 121105, count: 11400, grid_x: 480527 }, + { grid_y: 121105, count: 3800, grid_x: 480528 }, + { grid_y: 121105, count: 3800, grid_x: 480529 }, + { grid_y: 121105, count: 3800, grid_x: 480531 }, + { grid_y: 121105, count: 7600, grid_x: 480532 }, + { grid_y: 121105, count: 7600, grid_x: 480533 }, + { grid_y: 121106, count: 3800, grid_x: 480464 }, + { grid_y: 121106, count: 7600, grid_x: 480465 }, + { grid_y: 121106, count: 3800, grid_x: 480466 }, + { grid_y: 121106, count: 3800, grid_x: 480469 }, + { grid_y: 121106, count: 3800, grid_x: 480471 }, + { grid_y: 121106, count: 3800, grid_x: 480472 }, + { grid_y: 121106, count: 3800, grid_x: 480473 }, + { grid_y: 121106, count: 3800, grid_x: 480476 }, + { grid_y: 121106, count: 11400, grid_x: 480479 }, + { grid_y: 121106, count: 15200, grid_x: 480480 }, + { grid_y: 121106, count: 3800, grid_x: 480484 }, + { grid_y: 121106, count: 3800, grid_x: 480487 }, + { grid_y: 121106, count: 3800, grid_x: 480488 }, + { grid_y: 121106, count: 7600, grid_x: 480490 }, + { grid_y: 121106, count: 7600, grid_x: 480494 }, + { grid_y: 121106, count: 3800, grid_x: 480495 }, + { grid_y: 121106, count: 3800, grid_x: 480497 }, + { grid_y: 121106, count: 15200, grid_x: 480498 }, + { grid_y: 121106, count: 15200, grid_x: 480499 }, + { grid_y: 121106, count: 3800, grid_x: 480500 }, + { grid_y: 121106, count: 3800, grid_x: 480501 }, + { grid_y: 121106, count: 11400, grid_x: 480503 }, + { grid_y: 121106, count: 3800, grid_x: 480504 }, + { grid_y: 121106, count: 7600, grid_x: 480505 }, + { grid_y: 121106, count: 3800, grid_x: 480506 }, + { grid_y: 121106, count: 11400, grid_x: 480507 }, + { grid_y: 121106, count: 3800, grid_x: 480508 }, + { grid_y: 121106, count: 3800, grid_x: 480509 }, + { grid_y: 121106, count: 3800, grid_x: 480511 }, + { grid_y: 121106, count: 3800, grid_x: 480513 }, + { grid_y: 121106, count: 3800, grid_x: 480514 }, + { grid_y: 121106, count: 3800, grid_x: 480515 }, + { grid_y: 121106, count: 3800, grid_x: 480519 }, + { grid_y: 121106, count: 7600, grid_x: 480520 }, + { grid_y: 121106, count: 3800, grid_x: 480523 }, + { grid_y: 121106, count: 11400, grid_x: 480527 }, + { grid_y: 121106, count: 7600, grid_x: 480528 }, + { grid_y: 121106, count: 3800, grid_x: 480529 }, + { grid_y: 121106, count: 3800, grid_x: 480530 }, + { grid_y: 121106, count: 3800, grid_x: 480532 }, + { grid_y: 121106, count: 7600, grid_x: 480533 }, + { grid_y: 121107, count: 7600, grid_x: 480459 }, + { grid_y: 121107, count: 7600, grid_x: 480461 }, + { grid_y: 121107, count: 3800, grid_x: 480462 }, + { grid_y: 121107, count: 3800, grid_x: 480464 }, + { grid_y: 121107, count: 3800, grid_x: 480466 }, + { grid_y: 121107, count: 3800, grid_x: 480467 }, + { grid_y: 121107, count: 3800, grid_x: 480471 }, + { grid_y: 121107, count: 3800, grid_x: 480472 }, + { grid_y: 121107, count: 3800, grid_x: 480478 }, + { grid_y: 121107, count: 3800, grid_x: 480479 }, + { grid_y: 121107, count: 7600, grid_x: 480480 }, + { grid_y: 121107, count: 3800, grid_x: 480483 }, + { grid_y: 121107, count: 3800, grid_x: 480485 }, + { grid_y: 121107, count: 7600, grid_x: 480497 }, + { grid_y: 121107, count: 11400, grid_x: 480498 }, + { grid_y: 121107, count: 19000, grid_x: 480499 }, + { grid_y: 121107, count: 11400, grid_x: 480500 }, + { grid_y: 121107, count: 3800, grid_x: 480501 }, + { grid_y: 121107, count: 3800, grid_x: 480503 }, + { grid_y: 121107, count: 7600, grid_x: 480507 }, + { grid_y: 121107, count: 15200, grid_x: 480508 }, + { grid_y: 121107, count: 3800, grid_x: 480510 }, + { grid_y: 121107, count: 3800, grid_x: 480512 }, + { grid_y: 121107, count: 7600, grid_x: 480513 }, + { grid_y: 121107, count: 7600, grid_x: 480514 }, + { grid_y: 121107, count: 3800, grid_x: 480516 }, + { grid_y: 121107, count: 7600, grid_x: 480517 }, + { grid_y: 121107, count: 3800, grid_x: 480520 }, + { grid_y: 121107, count: 11400, grid_x: 480522 }, + { grid_y: 121107, count: 7600, grid_x: 480523 }, + { grid_y: 121107, count: 3800, grid_x: 480524 }, + { grid_y: 121107, count: 7600, grid_x: 480525 }, + { grid_y: 121107, count: 3800, grid_x: 480526 }, + { grid_y: 121107, count: 3800, grid_x: 480527 }, + { grid_y: 121107, count: 3800, grid_x: 480528 }, + { grid_y: 121107, count: 7600, grid_x: 480529 }, + { grid_y: 121107, count: 7600, grid_x: 480532 }, + { grid_y: 121107, count: 7600, grid_x: 480533 }, + { grid_y: 121108, count: 7600, grid_x: 480459 }, + { grid_y: 121108, count: 7600, grid_x: 480460 }, + { grid_y: 121108, count: 3800, grid_x: 480461 }, + { grid_y: 121108, count: 3800, grid_x: 480464 }, + { grid_y: 121108, count: 3800, grid_x: 480495 }, + { grid_y: 121108, count: 3800, grid_x: 480497 }, + { grid_y: 121108, count: 15200, grid_x: 480498 }, + { grid_y: 121108, count: 19000, grid_x: 480499 }, + { grid_y: 121108, count: 11400, grid_x: 480500 }, + { grid_y: 121108, count: 11400, grid_x: 480501 }, + { grid_y: 121108, count: 11400, grid_x: 480502 }, + { grid_y: 121108, count: 11400, grid_x: 480503 }, + { grid_y: 121108, count: 7600, grid_x: 480507 }, + { grid_y: 121108, count: 3800, grid_x: 480513 }, + { grid_y: 121108, count: 3800, grid_x: 480514 }, + { grid_y: 121108, count: 3800, grid_x: 480515 }, + { grid_y: 121108, count: 11400, grid_x: 480516 }, + { grid_y: 121108, count: 7600, grid_x: 480517 }, + { grid_y: 121108, count: 3800, grid_x: 480518 }, + { grid_y: 121108, count: 3800, grid_x: 480519 }, + { grid_y: 121108, count: 3800, grid_x: 480520 }, + { grid_y: 121108, count: 3800, grid_x: 480524 }, + { grid_y: 121108, count: 3800, grid_x: 480526 }, + { grid_y: 121108, count: 7600, grid_x: 480527 }, + { grid_y: 121108, count: 3800, grid_x: 480528 }, + { grid_y: 121108, count: 3800, grid_x: 480529 }, + { grid_y: 121108, count: 3800, grid_x: 480530 }, + { grid_y: 121108, count: 7600, grid_x: 480533 }, + { grid_y: 121109, count: 7600, grid_x: 480459 }, + { grid_y: 121109, count: 7600, grid_x: 480460 }, + { grid_y: 121109, count: 7600, grid_x: 480496 }, + { grid_y: 121109, count: 7600, grid_x: 480497 }, + { grid_y: 121109, count: 7600, grid_x: 480498 }, + { grid_y: 121109, count: 11400, grid_x: 480499 }, + { grid_y: 121109, count: 7600, grid_x: 480500 }, + { grid_y: 121109, count: 3800, grid_x: 480501 }, + { grid_y: 121109, count: 11400, grid_x: 480502 }, + { grid_y: 121109, count: 3800, grid_x: 480503 }, + { grid_y: 121109, count: 3800, grid_x: 480506 }, + { grid_y: 121109, count: 7600, grid_x: 480507 }, + { grid_y: 121109, count: 3800, grid_x: 480508 }, + { grid_y: 121109, count: 3800, grid_x: 480510 }, + { grid_y: 121109, count: 3800, grid_x: 480513 }, + { grid_y: 121109, count: 7600, grid_x: 480514 }, + { grid_y: 121109, count: 7600, grid_x: 480516 }, + { grid_y: 121109, count: 11400, grid_x: 480517 }, + { grid_y: 121109, count: 3800, grid_x: 480518 }, + { grid_y: 121109, count: 3800, grid_x: 480523 }, + { grid_y: 121109, count: 3800, grid_x: 480531 }, + { grid_y: 121109, count: 3800, grid_x: 480533 }, + { grid_y: 121110, count: 7600, grid_x: 480459 }, + { grid_y: 121110, count: 3800, grid_x: 480460 }, + { grid_y: 121110, count: 3800, grid_x: 480461 }, + { grid_y: 121110, count: 3800, grid_x: 480465 }, + { grid_y: 121110, count: 3800, grid_x: 480467 }, + { grid_y: 121110, count: 3800, grid_x: 480471 }, + { grid_y: 121110, count: 3800, grid_x: 480478 }, + { grid_y: 121110, count: 3800, grid_x: 480479 }, + { grid_y: 121110, count: 3800, grid_x: 480489 }, + { grid_y: 121110, count: 7600, grid_x: 480497 }, + { grid_y: 121110, count: 7600, grid_x: 480498 }, + { grid_y: 121110, count: 7600, grid_x: 480499 }, + { grid_y: 121110, count: 7600, grid_x: 480502 }, + { grid_y: 121110, count: 3800, grid_x: 480504 }, + { grid_y: 121110, count: 3800, grid_x: 480510 }, + { grid_y: 121110, count: 7600, grid_x: 480511 }, + { grid_y: 121110, count: 3800, grid_x: 480512 }, + { grid_y: 121110, count: 11400, grid_x: 480516 }, + { grid_y: 121110, count: 7600, grid_x: 480517 }, + { grid_y: 121110, count: 3800, grid_x: 480518 }, + { grid_y: 121110, count: 7600, grid_x: 480519 }, + { grid_y: 121110, count: 3800, grid_x: 480521 }, + { grid_y: 121110, count: 3800, grid_x: 480523 }, + { grid_y: 121110, count: 3800, grid_x: 480526 }, + { grid_y: 121111, count: 3800, grid_x: 480460 }, + { grid_y: 121111, count: 3800, grid_x: 480493 }, + { grid_y: 121111, count: 3800, grid_x: 480496 }, + { grid_y: 121111, count: 11400, grid_x: 480500 }, + { grid_y: 121111, count: 3800, grid_x: 480501 }, + { grid_y: 121111, count: 7600, grid_x: 480502 }, + { grid_y: 121111, count: 3800, grid_x: 480503 }, + { grid_y: 121111, count: 3800, grid_x: 480504 }, + { grid_y: 121111, count: 3800, grid_x: 480505 }, + { grid_y: 121111, count: 3800, grid_x: 480506 }, + { grid_y: 121111, count: 3800, grid_x: 480511 }, + { grid_y: 121111, count: 3800, grid_x: 480515 }, + { grid_y: 121111, count: 3800, grid_x: 480516 }, + { grid_y: 121111, count: 7600, grid_x: 480517 }, + { grid_y: 121111, count: 3800, grid_x: 480528 }, + { grid_y: 121112, count: 3800, grid_x: 480459 }, + { grid_y: 121112, count: 3800, grid_x: 480460 }, + { grid_y: 121112, count: 3800, grid_x: 480465 }, + { grid_y: 121112, count: 3800, grid_x: 480467 }, + { grid_y: 121112, count: 3800, grid_x: 480478 }, + { grid_y: 121112, count: 3800, grid_x: 480479 }, + { grid_y: 121112, count: 7600, grid_x: 480496 }, + { grid_y: 121112, count: 7600, grid_x: 480500 }, + { grid_y: 121112, count: 7600, grid_x: 480501 }, + { grid_y: 121112, count: 7600, grid_x: 480505 }, + { grid_y: 121112, count: 3800, grid_x: 480506 }, + { grid_y: 121112, count: 3800, grid_x: 480512 }, + { grid_y: 121112, count: 3800, grid_x: 480519 }, + { grid_y: 121112, count: 3800, grid_x: 480525 }, + { grid_y: 121112, count: 3800, grid_x: 480530 }, + { grid_y: 121112, count: 3800, grid_x: 480532 }, + { grid_y: 121112, count: 3800, grid_x: 480533 }, + { grid_y: 121113, count: 3800, grid_x: 480459 }, + { grid_y: 121113, count: 3800, grid_x: 480460 }, + { grid_y: 121113, count: 3800, grid_x: 480462 }, + { grid_y: 121113, count: 3800, grid_x: 480463 }, + { grid_y: 121113, count: 3800, grid_x: 480466 }, + { grid_y: 121113, count: 7600, grid_x: 480479 }, + { grid_y: 121113, count: 3800, grid_x: 480482 }, + { grid_y: 121113, count: 7600, grid_x: 480483 }, + { grid_y: 121113, count: 3800, grid_x: 480485 }, + { grid_y: 121113, count: 3800, grid_x: 480496 }, + { grid_y: 121113, count: 3800, grid_x: 480497 }, + { grid_y: 121113, count: 3800, grid_x: 480498 }, + { grid_y: 121113, count: 7600, grid_x: 480499 }, + { grid_y: 121113, count: 7600, grid_x: 480500 }, + { grid_y: 121113, count: 3800, grid_x: 480501 }, + { grid_y: 121113, count: 3800, grid_x: 480502 }, + { grid_y: 121113, count: 3800, grid_x: 480505 }, + { grid_y: 121113, count: 3800, grid_x: 480506 }, + { grid_y: 121113, count: 3800, grid_x: 480507 }, + { grid_y: 121113, count: 3800, grid_x: 480514 }, + { grid_y: 121113, count: 3800, grid_x: 480517 }, + { grid_y: 121113, count: 7600, grid_x: 480518 }, + { grid_y: 121113, count: 7600, grid_x: 480522 }, + { grid_y: 121113, count: 3800, grid_x: 480527 }, + { grid_y: 121113, count: 3800, grid_x: 480530 }, + { grid_y: 121114, count: 3800, grid_x: 480459 }, + { grid_y: 121114, count: 3800, grid_x: 480460 }, + { grid_y: 121114, count: 3800, grid_x: 480462 }, + { grid_y: 121114, count: 3800, grid_x: 480463 }, + { grid_y: 121114, count: 3800, grid_x: 480466 }, + { grid_y: 121114, count: 3800, grid_x: 480467 }, + { grid_y: 121114, count: 3800, grid_x: 480468 }, + { grid_y: 121114, count: 3800, grid_x: 480471 }, + { grid_y: 121114, count: 7600, grid_x: 480474 }, + { grid_y: 121114, count: 3800, grid_x: 480475 }, + { grid_y: 121114, count: 7600, grid_x: 480478 }, + { grid_y: 121114, count: 7600, grid_x: 480479 }, + { grid_y: 121114, count: 3800, grid_x: 480480 }, + { grid_y: 121114, count: 7600, grid_x: 480481 }, + { grid_y: 121114, count: 15200, grid_x: 480482 }, + { grid_y: 121114, count: 3800, grid_x: 480483 }, + { grid_y: 121114, count: 7600, grid_x: 480484 }, + { grid_y: 121114, count: 3800, grid_x: 480485 }, + { grid_y: 121114, count: 7600, grid_x: 480486 }, + { grid_y: 121114, count: 7600, grid_x: 480491 }, + { grid_y: 121114, count: 3800, grid_x: 480496 }, + { grid_y: 121114, count: 7600, grid_x: 480497 }, + { grid_y: 121114, count: 7600, grid_x: 480498 }, + { grid_y: 121114, count: 7600, grid_x: 480500 }, + { grid_y: 121114, count: 11400, grid_x: 480501 }, + { grid_y: 121114, count: 3800, grid_x: 480502 }, + { grid_y: 121114, count: 3800, grid_x: 480507 }, + { grid_y: 121114, count: 7600, grid_x: 480508 }, + { grid_y: 121114, count: 7600, grid_x: 480510 }, + { grid_y: 121114, count: 3800, grid_x: 480511 }, + { grid_y: 121114, count: 7600, grid_x: 480515 }, + { grid_y: 121114, count: 3800, grid_x: 480524 }, + { grid_y: 121114, count: 3800, grid_x: 480533 }, + { grid_y: 121115, count: 3800, grid_x: 480460 }, + { grid_y: 121115, count: 3800, grid_x: 480468 }, + { grid_y: 121115, count: 3800, grid_x: 480470 }, + { grid_y: 121115, count: 3800, grid_x: 480471 }, + { grid_y: 121115, count: 7600, grid_x: 480483 }, + { grid_y: 121115, count: 7600, grid_x: 480484 }, + { grid_y: 121115, count: 11400, grid_x: 480485 }, + { grid_y: 121115, count: 3800, grid_x: 480486 }, + { grid_y: 121115, count: 3800, grid_x: 480491 }, + { grid_y: 121115, count: 3800, grid_x: 480494 }, + { grid_y: 121115, count: 7600, grid_x: 480496 }, + { grid_y: 121115, count: 3800, grid_x: 480499 }, + { grid_y: 121115, count: 7600, grid_x: 480501 }, + { grid_y: 121115, count: 3800, grid_x: 480507 }, + { grid_y: 121115, count: 3800, grid_x: 480511 }, + { grid_y: 121115, count: 7600, grid_x: 480515 }, + { grid_y: 121115, count: 11400, grid_x: 480516 }, + { grid_y: 121115, count: 3800, grid_x: 480517 }, + { grid_y: 121115, count: 3800, grid_x: 480527 }, + { grid_y: 121115, count: 3800, grid_x: 480528 }, + { grid_y: 121116, count: 3800, grid_x: 480465 }, + { grid_y: 121116, count: 7600, grid_x: 480468 }, + { grid_y: 121116, count: 3800, grid_x: 480471 }, + { grid_y: 121116, count: 3800, grid_x: 480476 }, + { grid_y: 121116, count: 7600, grid_x: 480478 }, + { grid_y: 121116, count: 7600, grid_x: 480479 }, + { grid_y: 121116, count: 3800, grid_x: 480480 }, + { grid_y: 121116, count: 3800, grid_x: 480482 }, + { grid_y: 121116, count: 7600, grid_x: 480483 }, + { grid_y: 121116, count: 11400, grid_x: 480484 }, + { grid_y: 121116, count: 11400, grid_x: 480485 }, + { grid_y: 121116, count: 7600, grid_x: 480487 }, + { grid_y: 121116, count: 3800, grid_x: 480489 }, + { grid_y: 121116, count: 3800, grid_x: 480491 }, + { grid_y: 121116, count: 3800, grid_x: 480492 }, + { grid_y: 121116, count: 3800, grid_x: 480493 }, + { grid_y: 121116, count: 3800, grid_x: 480494 }, + { grid_y: 121116, count: 3800, grid_x: 480501 }, + { grid_y: 121116, count: 3800, grid_x: 480502 }, + { grid_y: 121116, count: 3800, grid_x: 480503 }, + { grid_y: 121116, count: 3800, grid_x: 480507 }, + { grid_y: 121116, count: 3800, grid_x: 480509 }, + { grid_y: 121116, count: 3800, grid_x: 480510 }, + { grid_y: 121116, count: 3800, grid_x: 480512 }, + { grid_y: 121116, count: 7600, grid_x: 480515 }, + { grid_y: 121116, count: 15200, grid_x: 480516 }, + { grid_y: 121116, count: 3800, grid_x: 480533 }, + { grid_y: 121117, count: 3800, grid_x: 480459 }, + { grid_y: 121117, count: 3800, grid_x: 480468 }, + { grid_y: 121117, count: 3800, grid_x: 480470 }, + { grid_y: 121117, count: 3800, grid_x: 480477 }, + { grid_y: 121117, count: 3800, grid_x: 480478 }, + { grid_y: 121117, count: 3800, grid_x: 480480 }, + { grid_y: 121117, count: 3800, grid_x: 480482 }, + { grid_y: 121117, count: 7600, grid_x: 480483 }, + { grid_y: 121117, count: 7600, grid_x: 480484 }, + { grid_y: 121117, count: 11400, grid_x: 480485 }, + { grid_y: 121117, count: 7600, grid_x: 480486 }, + { grid_y: 121117, count: 7600, grid_x: 480487 }, + { grid_y: 121117, count: 11400, grid_x: 480488 }, + { grid_y: 121117, count: 7600, grid_x: 480495 }, + { grid_y: 121117, count: 3800, grid_x: 480496 }, + { grid_y: 121117, count: 3800, grid_x: 480497 }, + { grid_y: 121117, count: 3800, grid_x: 480509 }, + { grid_y: 121117, count: 3800, grid_x: 480510 }, + { grid_y: 121117, count: 3800, grid_x: 480516 }, + { grid_y: 121117, count: 3800, grid_x: 480520 }, + { grid_y: 121117, count: 7600, grid_x: 480526 }, + { grid_y: 121117, count: 3800, grid_x: 480528 }, + { grid_y: 121117, count: 3800, grid_x: 480533 }, + { grid_y: 121118, count: 3800, grid_x: 480459 }, + { grid_y: 121118, count: 3800, grid_x: 480460 }, + { grid_y: 121118, count: 3800, grid_x: 480478 }, + { grid_y: 121118, count: 3800, grid_x: 480481 }, + { grid_y: 121118, count: 3800, grid_x: 480482 }, + { grid_y: 121118, count: 7600, grid_x: 480483 }, + { grid_y: 121118, count: 7600, grid_x: 480484 }, + { grid_y: 121118, count: 3800, grid_x: 480486 }, + { grid_y: 121118, count: 7600, grid_x: 480487 }, + { grid_y: 121118, count: 7600, grid_x: 480488 }, + { grid_y: 121118, count: 7600, grid_x: 480514 }, + { grid_y: 121118, count: 3800, grid_x: 480516 }, + { grid_y: 121118, count: 3800, grid_x: 480517 }, + { grid_y: 121118, count: 3800, grid_x: 480518 }, + { grid_y: 121118, count: 3800, grid_x: 480521 }, + { grid_y: 121118, count: 3800, grid_x: 480528 }, + { grid_y: 121118, count: 3800, grid_x: 480533 }, + { grid_y: 121119, count: 3800, grid_x: 480467 }, + { grid_y: 121119, count: 3800, grid_x: 480469 }, + { grid_y: 121119, count: 3800, grid_x: 480478 }, + { grid_y: 121119, count: 3800, grid_x: 480479 }, + { grid_y: 121119, count: 3800, grid_x: 480483 }, + { grid_y: 121119, count: 3800, grid_x: 480485 }, + { grid_y: 121119, count: 7600, grid_x: 480486 }, + { grid_y: 121119, count: 7600, grid_x: 480487 }, + { grid_y: 121119, count: 3800, grid_x: 480514 }, + { grid_y: 121119, count: 3800, grid_x: 480518 }, + { grid_y: 121119, count: 3800, grid_x: 480526 }, + { grid_y: 121120, count: 3800, grid_x: 480466 }, + { grid_y: 121120, count: 3800, grid_x: 480468 }, + { grid_y: 121120, count: 3800, grid_x: 480479 }, + { grid_y: 121120, count: 3800, grid_x: 480480 }, + { grid_y: 121120, count: 3800, grid_x: 480483 }, + { grid_y: 121120, count: 3800, grid_x: 480484 }, + { grid_y: 121120, count: 3800, grid_x: 480485 }, + { grid_y: 121120, count: 7600, grid_x: 480486 }, + { grid_y: 121120, count: 3800, grid_x: 480491 }, + { grid_y: 121120, count: 3800, grid_x: 480497 }, + { grid_y: 121120, count: 3800, grid_x: 480509 }, + { grid_y: 121120, count: 3800, grid_x: 480515 }, + { grid_y: 121120, count: 3800, grid_x: 480518 }, + { grid_y: 121120, count: 3800, grid_x: 480526 }, + { grid_y: 121121, count: 3800, grid_x: 480472 }, + { grid_y: 121121, count: 3800, grid_x: 480473 }, + { grid_y: 121121, count: 7600, grid_x: 480480 }, + { grid_y: 121121, count: 3800, grid_x: 480481 }, + { grid_y: 121121, count: 7600, grid_x: 480483 }, + { grid_y: 121121, count: 7600, grid_x: 480484 }, + { grid_y: 121121, count: 7600, grid_x: 480485 }, + { grid_y: 121121, count: 7600, grid_x: 480486 }, + { grid_y: 121121, count: 3800, grid_x: 480495 }, + { grid_y: 121122, count: 3800, grid_x: 480474 }, + { grid_y: 121122, count: 3800, grid_x: 480479 }, + { grid_y: 121122, count: 3800, grid_x: 480481 }, + { grid_y: 121122, count: 3800, grid_x: 480483 }, + { grid_y: 121122, count: 7600, grid_x: 480484 }, + { grid_y: 121122, count: 3800, grid_x: 480485 }, + { grid_y: 121122, count: 7600, grid_x: 480491 }, + { grid_y: 121122, count: 7600, grid_x: 480492 }, + { grid_y: 121122, count: 7600, grid_x: 480493 }, + { grid_y: 121122, count: 3800, grid_x: 480494 }, + { grid_y: 121122, count: 7600, grid_x: 480495 }, + { grid_y: 121122, count: 3800, grid_x: 480510 }, + { grid_y: 121122, count: 3800, grid_x: 480517 }, + { grid_y: 121123, count: 7600, grid_x: 480469 }, + { grid_y: 121123, count: 7600, grid_x: 480477 }, + { grid_y: 121123, count: 3800, grid_x: 480478 }, + { grid_y: 121123, count: 3800, grid_x: 480479 }, + { grid_y: 121123, count: 11400, grid_x: 480481 }, + { grid_y: 121123, count: 7600, grid_x: 480482 }, + { grid_y: 121123, count: 7600, grid_x: 480484 }, + { grid_y: 121123, count: 7600, grid_x: 480485 }, + { grid_y: 121123, count: 3800, grid_x: 480486 }, + { grid_y: 121123, count: 3800, grid_x: 480491 }, + { grid_y: 121123, count: 3800, grid_x: 480492 }, + { grid_y: 121123, count: 3800, grid_x: 480493 }, + { grid_y: 121123, count: 7600, grid_x: 480495 }, + { grid_y: 121123, count: 3800, grid_x: 480509 }, + { grid_y: 121123, count: 3800, grid_x: 480517 }, + { grid_y: 121123, count: 7600, grid_x: 480518 }, + { grid_y: 121124, count: 3800, grid_x: 480469 }, + { grid_y: 121124, count: 3800, grid_x: 480474 }, + { grid_y: 121124, count: 3800, grid_x: 480476 }, + { grid_y: 121124, count: 3800, grid_x: 480478 }, + { grid_y: 121124, count: 3800, grid_x: 480480 }, + { grid_y: 121124, count: 3800, grid_x: 480481 }, + { grid_y: 121124, count: 3800, grid_x: 480483 }, + { grid_y: 121124, count: 3800, grid_x: 480485 }, + { grid_y: 121124, count: 3800, grid_x: 480487 }, + { grid_y: 121124, count: 3800, grid_x: 480493 }, + { grid_y: 121124, count: 3800, grid_x: 480505 }, + { grid_y: 121124, count: 3800, grid_x: 480530 }, + { grid_y: 121125, count: 3800, grid_x: 480466 }, + { grid_y: 121125, count: 3800, grid_x: 480472 }, + { grid_y: 121125, count: 3800, grid_x: 480477 }, + { grid_y: 121125, count: 3800, grid_x: 480478 }, + { grid_y: 121125, count: 7600, grid_x: 480479 }, + { grid_y: 121125, count: 3800, grid_x: 480480 }, + { grid_y: 121125, count: 3800, grid_x: 480483 }, + { grid_y: 121125, count: 3800, grid_x: 480484 }, + { grid_y: 121125, count: 7600, grid_x: 480488 }, + { grid_y: 121125, count: 3800, grid_x: 480496 }, + { grid_y: 121125, count: 3800, grid_x: 480497 }, + { grid_y: 121125, count: 3800, grid_x: 480509 }, + { grid_y: 121126, count: 3800, grid_x: 480459 }, + { grid_y: 121126, count: 3800, grid_x: 480469 }, + { grid_y: 121126, count: 7600, grid_x: 480470 }, + { grid_y: 121126, count: 7600, grid_x: 480472 }, + { grid_y: 121126, count: 3800, grid_x: 480474 }, + { grid_y: 121126, count: 7600, grid_x: 480478 }, + { grid_y: 121126, count: 3800, grid_x: 480479 }, + { grid_y: 121126, count: 15200, grid_x: 480480 }, + { grid_y: 121126, count: 15200, grid_x: 480483 }, + { grid_y: 121126, count: 7600, grid_x: 480485 }, + { grid_y: 121126, count: 3800, grid_x: 480486 }, + { grid_y: 121126, count: 3800, grid_x: 480489 }, + { grid_y: 121126, count: 3800, grid_x: 480517 }, + { grid_y: 121126, count: 3800, grid_x: 480529 }, + { grid_y: 121127, count: 3800, grid_x: 480460 }, + { grid_y: 121127, count: 7600, grid_x: 480465 }, + { grid_y: 121127, count: 3800, grid_x: 480468 }, + { grid_y: 121127, count: 3800, grid_x: 480470 }, + { grid_y: 121127, count: 11400, grid_x: 480472 }, + { grid_y: 121127, count: 7600, grid_x: 480473 }, + { grid_y: 121127, count: 3800, grid_x: 480477 }, + { grid_y: 121127, count: 3800, grid_x: 480478 }, + { grid_y: 121127, count: 15200, grid_x: 480479 }, + { grid_y: 121127, count: 11400, grid_x: 480480 }, + { grid_y: 121127, count: 3800, grid_x: 480482 }, + { grid_y: 121127, count: 38000, grid_x: 480483 }, + { grid_y: 121127, count: 3800, grid_x: 480484 }, + { grid_y: 121127, count: 3800, grid_x: 480486 }, + { grid_y: 121127, count: 3800, grid_x: 480487 }, + { grid_y: 121127, count: 3800, grid_x: 480488 }, + { grid_y: 121127, count: 3800, grid_x: 480493 }, + { grid_y: 121127, count: 3800, grid_x: 480496 }, + { grid_y: 121127, count: 3800, grid_x: 480515 }, + { grid_y: 121127, count: 3800, grid_x: 480517 }, + { grid_y: 121127, count: 3800, grid_x: 480519 }, + { grid_y: 121127, count: 3800, grid_x: 480522 }, + { grid_y: 121128, count: 3800, grid_x: 480459 }, + { grid_y: 121128, count: 3800, grid_x: 480463 }, + { grid_y: 121128, count: 3800, grid_x: 480465 }, + { grid_y: 121128, count: 3800, grid_x: 480467 }, + { grid_y: 121128, count: 3800, grid_x: 480469 }, + { grid_y: 121128, count: 11400, grid_x: 480470 }, + { grid_y: 121128, count: 3800, grid_x: 480471 }, + { grid_y: 121128, count: 3800, grid_x: 480472 }, + { grid_y: 121128, count: 3800, grid_x: 480473 }, + { grid_y: 121128, count: 3800, grid_x: 480474 }, + { grid_y: 121128, count: 7600, grid_x: 480475 }, + { grid_y: 121128, count: 3800, grid_x: 480476 }, + { grid_y: 121128, count: 3800, grid_x: 480483 }, + { grid_y: 121128, count: 7600, grid_x: 480484 }, + { grid_y: 121128, count: 11400, grid_x: 480486 }, + { grid_y: 121128, count: 11400, grid_x: 480487 }, + { grid_y: 121128, count: 3800, grid_x: 480488 }, + { grid_y: 121128, count: 3800, grid_x: 480490 }, + { grid_y: 121128, count: 3800, grid_x: 480495 }, + { grid_y: 121128, count: 11400, grid_x: 480496 }, + { grid_y: 121128, count: 7600, grid_x: 480498 }, + { grid_y: 121128, count: 7600, grid_x: 480499 }, + { grid_y: 121128, count: 3800, grid_x: 480507 }, + { grid_y: 121128, count: 3800, grid_x: 480509 }, + { grid_y: 121128, count: 3800, grid_x: 480515 }, + { grid_y: 121128, count: 3800, grid_x: 480517 }, + { grid_y: 121128, count: 3800, grid_x: 480523 }, + { grid_y: 121128, count: 3800, grid_x: 480531 }, + { grid_y: 121129, count: 3800, grid_x: 480467 }, + { grid_y: 121129, count: 3800, grid_x: 480468 }, + { grid_y: 121129, count: 7600, grid_x: 480469 }, + { grid_y: 121129, count: 3800, grid_x: 480470 }, + { grid_y: 121129, count: 7600, grid_x: 480471 }, + { grid_y: 121129, count: 30400, grid_x: 480472 }, + { grid_y: 121129, count: 7600, grid_x: 480473 }, + { grid_y: 121129, count: 3800, grid_x: 480479 }, + { grid_y: 121129, count: 7600, grid_x: 480480 }, + { grid_y: 121129, count: 7600, grid_x: 480481 }, + { grid_y: 121129, count: 3800, grid_x: 480482 }, + { grid_y: 121129, count: 3800, grid_x: 480483 }, + { grid_y: 121129, count: 3800, grid_x: 480486 }, + { grid_y: 121129, count: 3800, grid_x: 480487 }, + { grid_y: 121129, count: 3800, grid_x: 480490 }, + { grid_y: 121129, count: 3800, grid_x: 480492 }, + { grid_y: 121129, count: 3800, grid_x: 480493 }, + { grid_y: 121129, count: 3800, grid_x: 480494 }, + { grid_y: 121129, count: 3800, grid_x: 480498 }, + { grid_y: 121129, count: 7600, grid_x: 480500 }, + { grid_y: 121129, count: 3800, grid_x: 480502 }, + { grid_y: 121129, count: 7600, grid_x: 480511 }, + { grid_y: 121129, count: 7600, grid_x: 480514 }, + { grid_y: 121129, count: 7600, grid_x: 480518 }, + { grid_y: 121130, count: 3800, grid_x: 480468 }, + { grid_y: 121130, count: 7600, grid_x: 480470 }, + { grid_y: 121130, count: 7600, grid_x: 480471 }, + { grid_y: 121130, count: 7600, grid_x: 480472 }, + { grid_y: 121130, count: 3800, grid_x: 480476 }, + { grid_y: 121130, count: 3800, grid_x: 480477 }, + { grid_y: 121130, count: 7600, grid_x: 480481 }, + { grid_y: 121130, count: 3800, grid_x: 480482 }, + { grid_y: 121130, count: 3800, grid_x: 480485 }, + { grid_y: 121130, count: 3800, grid_x: 480492 }, + { grid_y: 121130, count: 7600, grid_x: 480494 }, + { grid_y: 121130, count: 3800, grid_x: 480497 }, + { grid_y: 121130, count: 3800, grid_x: 480498 }, + { grid_y: 121130, count: 3800, grid_x: 480500 }, + { grid_y: 121130, count: 3800, grid_x: 480503 }, + { grid_y: 121130, count: 3800, grid_x: 480506 }, + { grid_y: 121130, count: 7600, grid_x: 480507 }, + { grid_y: 121130, count: 3800, grid_x: 480509 }, + { grid_y: 121130, count: 7600, grid_x: 480510 }, + { grid_y: 121130, count: 3800, grid_x: 480511 }, + { grid_y: 121130, count: 7600, grid_x: 480514 }, + { grid_y: 121130, count: 3800, grid_x: 480527 }, + { grid_y: 121130, count: 3800, grid_x: 480530 }, + { grid_y: 121131, count: 3800, grid_x: 480459 }, + { grid_y: 121131, count: 3800, grid_x: 480468 }, + { grid_y: 121131, count: 3800, grid_x: 480471 }, + { grid_y: 121131, count: 3800, grid_x: 480478 }, + { grid_y: 121131, count: 3800, grid_x: 480485 }, + { grid_y: 121131, count: 3800, grid_x: 480486 }, + { grid_y: 121131, count: 3800, grid_x: 480489 }, + { grid_y: 121131, count: 3800, grid_x: 480490 }, + { grid_y: 121131, count: 7600, grid_x: 480499 }, + { grid_y: 121131, count: 3800, grid_x: 480507 }, + { grid_y: 121131, count: 3800, grid_x: 480508 }, + { grid_y: 121131, count: 3800, grid_x: 480509 }, + { grid_y: 121131, count: 19000, grid_x: 480515 }, + { grid_y: 121131, count: 7600, grid_x: 480516 }, + { grid_y: 121131, count: 7600, grid_x: 480517 }, + { grid_y: 121131, count: 3800, grid_x: 480526 }, + { grid_y: 121131, count: 3800, grid_x: 480529 }, + { grid_y: 121131, count: 3800, grid_x: 480533 }, + { grid_y: 121132, count: 7600, grid_x: 480469 }, + { grid_y: 121132, count: 3800, grid_x: 480470 }, + { grid_y: 121132, count: 3800, grid_x: 480472 }, + { grid_y: 121132, count: 3800, grid_x: 480474 }, + { grid_y: 121132, count: 3800, grid_x: 480479 }, + { grid_y: 121132, count: 3800, grid_x: 480480 }, + { grid_y: 121132, count: 3800, grid_x: 480489 }, + { grid_y: 121132, count: 3800, grid_x: 480495 }, + { grid_y: 121132, count: 3800, grid_x: 480497 }, + { grid_y: 121132, count: 3800, grid_x: 480499 }, + { grid_y: 121132, count: 3800, grid_x: 480503 }, + { grid_y: 121132, count: 3800, grid_x: 480508 }, + { grid_y: 121132, count: 3800, grid_x: 480519 }, + { grid_y: 121133, count: 3800, grid_x: 480464 }, + { grid_y: 121133, count: 3800, grid_x: 480466 }, + { grid_y: 121133, count: 3800, grid_x: 480477 }, + { grid_y: 121133, count: 3800, grid_x: 480478 }, + { grid_y: 121133, count: 3800, grid_x: 480482 }, + { grid_y: 121133, count: 3800, grid_x: 480490 }, + { grid_y: 121133, count: 3800, grid_x: 480491 }, + { grid_y: 121133, count: 7600, grid_x: 480497 }, + { grid_y: 121133, count: 3800, grid_x: 480498 }, + { grid_y: 121133, count: 3800, grid_x: 480499 }, + { grid_y: 121133, count: 3800, grid_x: 480502 }, + { grid_y: 121133, count: 3800, grid_x: 480516 }, + { grid_y: 121133, count: 3800, grid_x: 480519 }, + { grid_y: 121133, count: 3800, grid_x: 480520 }, + { grid_y: 121134, count: 3800, grid_x: 480468 }, + { grid_y: 121134, count: 7600, grid_x: 480477 }, + { grid_y: 121134, count: 3800, grid_x: 480481 }, + { grid_y: 121134, count: 7600, grid_x: 480482 }, + { grid_y: 121134, count: 3800, grid_x: 480484 }, + { grid_y: 121134, count: 3800, grid_x: 480485 }, + { grid_y: 121134, count: 3800, grid_x: 480493 }, + { grid_y: 121134, count: 3800, grid_x: 480501 }, + { grid_y: 121134, count: 3800, grid_x: 480508 }, + { grid_y: 121134, count: 3800, grid_x: 480514 }, + { grid_y: 121134, count: 3800, grid_x: 480516 }, + { grid_y: 121134, count: 3800, grid_x: 480519 }, + { grid_y: 121134, count: 3800, grid_x: 480520 }, + { grid_y: 121134, count: 3800, grid_x: 480526 }, + { grid_y: 121134, count: 3800, grid_x: 480527 }, + { grid_y: 121135, count: 3800, grid_x: 480460 }, + { grid_y: 121135, count: 3800, grid_x: 480477 }, + { grid_y: 121135, count: 3800, grid_x: 480481 }, + { grid_y: 121135, count: 7600, grid_x: 480482 }, + { grid_y: 121135, count: 11400, grid_x: 480483 }, + { grid_y: 121135, count: 7600, grid_x: 480484 }, + { grid_y: 121135, count: 3800, grid_x: 480486 }, + { grid_y: 121135, count: 3800, grid_x: 480489 }, + { grid_y: 121135, count: 3800, grid_x: 480493 }, + { grid_y: 121135, count: 3800, grid_x: 480503 }, + { grid_y: 121135, count: 3800, grid_x: 480510 }, + { grid_y: 121135, count: 3800, grid_x: 480529 }, + { grid_y: 121135, count: 3800, grid_x: 480533 } +]; diff --git a/test/unit/source/transfrom/hexagon.js b/test/unit/source/transfrom/hexagon.js new file mode 100644 index 0000000000..b0877e7b80 --- /dev/null +++ b/test/unit/source/transfrom/hexagon.js @@ -0,0 +1,21 @@ +import { expect } from 'chai'; +import { pointData } from '../../../asset/data/point'; +import { pointToHexbin } from '../../../../src/source/transform/hexagon'; +describe('hexagon Test', function() { + + it('pointToHexbin', function() { + const dataArray = pointData.map(item => { + const lng = 1e-6 * (250 * item.grid_x + 125), + lat = 1e-6 * (250 * item.grid_y + 125); + return { + v: item.count * 1, + coordinates: [ lng, lat ] + }; + }); + + const data = { + dataArray + }; + const hexgonGrid = pointToHexbin(data, { size: 100, field: 'count', method: 'sum' }); + }); +});