diff --git a/.changeset/clean-beers-try.md b/.changeset/clean-beers-try.md new file mode 100644 index 00000000000..7e6396a7f1a --- /dev/null +++ b/.changeset/clean-beers-try.md @@ -0,0 +1,5 @@ +--- +'@antv/l7-layers': patch +--- + +fix: mapbox 线图层的贴图变形 diff --git a/.changeset/cyan-badgers-argue.md b/.changeset/cyan-badgers-argue.md new file mode 100644 index 00000000000..fab83c3f3ec --- /dev/null +++ b/.changeset/cyan-badgers-argue.md @@ -0,0 +1,5 @@ +--- +'@antv/l7-layers': patch +--- + +fix: 解决 GeometryLayer 在不同底图上的渲染不一致情况 diff --git a/.changeset/famous-geese-know.md b/.changeset/famous-geese-know.md new file mode 100644 index 00000000000..981308127af --- /dev/null +++ b/.changeset/famous-geese-know.md @@ -0,0 +1,5 @@ +--- +'@antv/l7-renderer': patch +--- + +fix: 修复 bindings 缓存在 WebGPU 的问题 diff --git a/.changeset/five-singers-rush.md b/.changeset/five-singers-rush.md new file mode 100644 index 00000000000..63d2c0cdc33 --- /dev/null +++ b/.changeset/five-singers-rush.md @@ -0,0 +1,5 @@ +--- +'@antv/l7-component': patch +--- + +fix: 无地图与 MapLibre 模式移动 Marker 出错 diff --git a/.changeset/gold-fans-dream.md b/.changeset/gold-fans-dream.md new file mode 100644 index 00000000000..1e62c5acdbd --- /dev/null +++ b/.changeset/gold-fans-dream.md @@ -0,0 +1,5 @@ +--- +'@antv/l7-maps': patch +--- + +fix: 修复在 Map 上使用组件事件穿透到图层上的问题 diff --git a/.changeset/honest-schools-relate.md b/.changeset/honest-schools-relate.md new file mode 100644 index 00000000000..93774923f0e --- /dev/null +++ b/.changeset/honest-schools-relate.md @@ -0,0 +1,5 @@ +--- +'@antv/l7-layers': patch +--- + +fix: 修复热力蜂窝图层渲染空白 diff --git a/.changeset/large-pumas-provide.md b/.changeset/large-pumas-provide.md new file mode 100644 index 00000000000..7f9d79da86d --- /dev/null +++ b/.changeset/large-pumas-provide.md @@ -0,0 +1,5 @@ +--- +'@antv/l7-map': patch +--- + +refactor: 升级新版一方地图交互事件机制,解决抖动问题 diff --git a/.changeset/polite-apples-rule.md b/.changeset/polite-apples-rule.md new file mode 100644 index 00000000000..d158d296d42 --- /dev/null +++ b/.changeset/polite-apples-rule.md @@ -0,0 +1,5 @@ +--- +'@antv/l7-core': patch +--- + +fix: 在 WebGL2 拾取事件冒泡延迟问题 diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 00000000000..81a848729a7 --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,35 @@ +{ + "mode": "exit", + "tag": "beta", + "initialVersions": { + "@antv/l7-component": "2.21.10", + "@antv/l7-core": "2.21.10", + "@antv/l7": "2.21.10", + "@antv/l7-layers": "2.21.10", + "@antv/l7-map": "2.21.10", + "@antv/l7-maps": "2.21.10", + "@antv/l7-renderer": "2.21.10", + "@antv/l7-scene": "2.21.10", + "@antv/l7-source": "2.21.10", + "@antv/l7-test-utils": "2.21.10", + "@antv/l7-three": "2.21.10", + "@antv/l7-utils": "2.21.10", + "@antv/l7-site": "2.21.3" + }, + "changesets": [ + "clean-beers-try", + "cyan-badgers-argue", + "famous-geese-know", + "five-singers-rush", + "gold-fans-dream", + "honest-schools-relate", + "large-pumas-provide", + "polite-apples-rule", + "proud-flies-change", + "rude-crabs-cheer", + "slimy-starfishes-joke", + "sour-dodos-bake", + "sour-lemons-perform", + "tiny-seas-camp" + ] +} diff --git a/.changeset/rude-crabs-cheer.md b/.changeset/rude-crabs-cheer.md new file mode 100644 index 00000000000..a7c99918573 --- /dev/null +++ b/.changeset/rude-crabs-cheer.md @@ -0,0 +1,5 @@ +--- +'@antv/l7-maps': patch +--- + +fix: 天地图 setCenter 方法缺失 diff --git a/.changeset/slimy-starfishes-joke.md b/.changeset/slimy-starfishes-joke.md new file mode 100644 index 00000000000..031f4444f98 --- /dev/null +++ b/.changeset/slimy-starfishes-joke.md @@ -0,0 +1,9 @@ +--- +'@antv/l7-layers': patch +'@antv/l7-core': patch +'@antv/l7-maps': patch +--- + +fix: Mapbox/Maplibre 20 层级以上数据偏移问题 +fix: 修复点图层部分 shape 中心点计算有误 +fix: 修复立体面图层光照计算有误 diff --git a/.changeset/sour-dodos-bake.md b/.changeset/sour-dodos-bake.md new file mode 100644 index 00000000000..efb6509ccbd --- /dev/null +++ b/.changeset/sour-dodos-bake.md @@ -0,0 +1,5 @@ +--- +'@antv/l7-scene': patch +--- + +feat: 设置默认的渲染引擎为 g-device,优先使用 WebGL2 diff --git a/.changeset/sour-lemons-perform.md b/.changeset/sour-lemons-perform.md new file mode 100644 index 00000000000..8aaf7216e4d --- /dev/null +++ b/.changeset/sour-lemons-perform.md @@ -0,0 +1,5 @@ +--- +'@antv/l7-maps': minor +--- + +refactor: 高德地图联动升级 diff --git a/.changeset/tiny-seas-camp.md b/.changeset/tiny-seas-camp.md new file mode 100644 index 00000000000..c8ab41a6735 --- /dev/null +++ b/.changeset/tiny-seas-camp.md @@ -0,0 +1,5 @@ +--- +'@antv/l7-layers': patch +--- + +fix: mapbox 下部分面数据图层绘制异常 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0ed93e6f16c..2ad12cf515f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,10 +68,10 @@ jobs: # use xvfb-run run in ubuntu run: xvfb-run pnpm test-cover - - name: Upload test coverage - uses: coverallsapp/github-action@master - with: - github-token: ${{ secrets.GITHUB_TOKEN }} + # - name: Upload test coverage + # uses: coverallsapp/github-action@master + # with: + # github-token: ${{ secrets.GITHUB_TOKEN }} integration-test: runs-on: ubuntu-latest diff --git a/.prettierignore b/.prettierignore index 1caf0a0431e..54404306532 100644 --- a/.prettierignore +++ b/.prettierignore @@ -29,3 +29,5 @@ site/.dumi/tmp-production/ site/public/ site/public_site/ +# examples for data +examples/data/ diff --git a/__tests__/integration/gallery.spec.ts b/__tests__/integration/gallery.spec.ts index b968cb37a5b..a644448dd6f 100644 --- a/__tests__/integration/gallery.spec.ts +++ b/__tests__/integration/gallery.spec.ts @@ -3,10 +3,14 @@ import { generateCanvasTestCases } from './utils/generator'; const TEST_CASES = [ { name: 'fujian', - sleepTime: 500, + sleepTime: 1000, + }, + { + name: 'variFlight', + sleepTime: 1000, }, ]; describe('Gallery Snapshot', () => { - generateCanvasTestCases('Gallery', TEST_CASES); + generateCanvasTestCases('gallery', TEST_CASES); }); diff --git a/__tests__/integration/heatmap.spec.ts b/__tests__/integration/heatmap.spec.ts new file mode 100644 index 00000000000..e26513946e6 --- /dev/null +++ b/__tests__/integration/heatmap.spec.ts @@ -0,0 +1,17 @@ +import { generateCanvasTestCases } from './utils/generator'; + +const TEST_CASES = [ + { + name: 'normal', + }, + { + name: 'grid', + }, + { + name: 'hexagon', + }, +]; + +describe('Heatmap Snapshot', () => { + generateCanvasTestCases('heatmap', TEST_CASES); +}); diff --git a/__tests__/integration/line.spec.ts b/__tests__/integration/line.spec.ts index a70793f62fd..932e7c8198f 100644 --- a/__tests__/integration/line.spec.ts +++ b/__tests__/integration/line.spec.ts @@ -2,28 +2,33 @@ import { generateCanvasTestCases } from './utils/generator'; const TEST_CASES = [ { - name: 'arc', - sleepTime: 500, + name: 'simple', }, { - name: 'arc_plane', - sleepTime: 500, + name: 'normal', }, - { - name: 'flow', - sleepTime: 800, + name: 'dash', + snapshot: false, + }, + { + name: 'wall', }, { name: 'arc', - sleepTime: 600, }, { - name: 'dash', + name: 'arc3D', + }, + { + name: 'greatcircle', + }, + { + name: 'flow', sleepTime: 500, }, ]; describe('Line Snapshot', () => { - generateCanvasTestCases('Line', TEST_CASES); + generateCanvasTestCases('line', TEST_CASES); }); diff --git a/__tests__/integration/mask.spec.ts b/__tests__/integration/mask.spec.ts index 5fc9456cf54..ad52db2ec39 100644 --- a/__tests__/integration/mask.spec.ts +++ b/__tests__/integration/mask.spec.ts @@ -11,5 +11,5 @@ const TEST_CASES = [ ]; describe('Mask Snapshot', () => { - generateCanvasTestCases('Mask', TEST_CASES); + generateCanvasTestCases('mask', TEST_CASES); }); diff --git a/__tests__/integration/point.spec.ts b/__tests__/integration/point.spec.ts index d937ec5ce32..4b9826e4074 100644 --- a/__tests__/integration/point.spec.ts +++ b/__tests__/integration/point.spec.ts @@ -8,19 +8,24 @@ const TEST_CASES = [ name: 'column', }, { - name: 'fill_image', + name: 'dot', + snapshot: false, }, { name: 'fill', }, - // { - // name: 'image', - // }, + { + name: 'fillImage', + }, + { + name: 'image', + snapshot: false, + }, { name: 'text', }, ]; describe('Point Snapshot', () => { - generateCanvasTestCases('Point', TEST_CASES); + generateCanvasTestCases('point', TEST_CASES); }); diff --git a/__tests__/integration/polygon.spec.ts b/__tests__/integration/polygon.spec.ts index 096e1f711f1..e8aa1c95ca8 100644 --- a/__tests__/integration/polygon.spec.ts +++ b/__tests__/integration/polygon.spec.ts @@ -3,24 +3,29 @@ import { generateCanvasTestCases } from './utils/generator'; const TEST_CASES = [ { name: 'extrude', + sleepTime: 500, + }, + { + name: 'extrusion', + sleepTime: 500, }, { name: 'fill', }, { name: 'ocean', - snapshots: false, + snapshot: false, }, { name: 'texture', - snapshots: false, + snapshot: false, }, { name: 'water', - snapshots: false, + snapshot: false, }, ]; describe('Polygon Snapshot', () => { - generateCanvasTestCases('Polygon', TEST_CASES); + generateCanvasTestCases('polygon', TEST_CASES); }); diff --git a/__tests__/integration/snapshots/Gallery_fujian.png b/__tests__/integration/snapshots/Gallery_fujian.png deleted file mode 100644 index a3c58293139..00000000000 Binary files a/__tests__/integration/snapshots/Gallery_fujian.png and /dev/null differ diff --git a/__tests__/integration/snapshots/Line_arc.png b/__tests__/integration/snapshots/Line_arc.png deleted file mode 100644 index 776f196e680..00000000000 Binary files a/__tests__/integration/snapshots/Line_arc.png and /dev/null differ diff --git a/__tests__/integration/snapshots/Line_arc_plane.png b/__tests__/integration/snapshots/Line_arc_plane.png deleted file mode 100644 index fd35924e2e5..00000000000 Binary files a/__tests__/integration/snapshots/Line_arc_plane.png and /dev/null differ diff --git a/__tests__/integration/snapshots/Line_dash.png b/__tests__/integration/snapshots/Line_dash.png deleted file mode 100644 index 33ada38a882..00000000000 Binary files a/__tests__/integration/snapshots/Line_dash.png and /dev/null differ diff --git a/__tests__/integration/snapshots/Line_flow.png b/__tests__/integration/snapshots/Line_flow.png deleted file mode 100644 index dda247b4287..00000000000 Binary files a/__tests__/integration/snapshots/Line_flow.png and /dev/null differ diff --git a/__tests__/integration/snapshots/Mask_multi.png b/__tests__/integration/snapshots/Mask_multi.png deleted file mode 100644 index 25d32428c0f..00000000000 Binary files a/__tests__/integration/snapshots/Mask_multi.png and /dev/null differ diff --git a/__tests__/integration/snapshots/Mask_single.png b/__tests__/integration/snapshots/Mask_single.png deleted file mode 100644 index 0376e32ba52..00000000000 Binary files a/__tests__/integration/snapshots/Mask_single.png and /dev/null differ diff --git a/__tests__/integration/snapshots/Point_billboard.png b/__tests__/integration/snapshots/Point_billboard.png deleted file mode 100644 index 89cf9f30d08..00000000000 Binary files a/__tests__/integration/snapshots/Point_billboard.png and /dev/null differ diff --git a/__tests__/integration/snapshots/Point_column.png b/__tests__/integration/snapshots/Point_column.png deleted file mode 100644 index 64c4af9e570..00000000000 Binary files a/__tests__/integration/snapshots/Point_column.png and /dev/null differ diff --git a/__tests__/integration/snapshots/Point_fill.png b/__tests__/integration/snapshots/Point_fill.png deleted file mode 100644 index 60e86af5c67..00000000000 Binary files a/__tests__/integration/snapshots/Point_fill.png and /dev/null differ diff --git a/__tests__/integration/snapshots/Point_fill_image.png b/__tests__/integration/snapshots/Point_fill_image.png deleted file mode 100644 index 4ee836e6899..00000000000 Binary files a/__tests__/integration/snapshots/Point_fill_image.png and /dev/null differ diff --git a/__tests__/integration/snapshots/Point_text.png b/__tests__/integration/snapshots/Point_text.png deleted file mode 100644 index b4c065eb075..00000000000 Binary files a/__tests__/integration/snapshots/Point_text.png and /dev/null differ diff --git a/__tests__/integration/snapshots/Polygon_extrude.png b/__tests__/integration/snapshots/Polygon_extrude.png deleted file mode 100644 index 768cb016b6f..00000000000 Binary files a/__tests__/integration/snapshots/Polygon_extrude.png and /dev/null differ diff --git a/__tests__/integration/snapshots/Polygon_fill.png b/__tests__/integration/snapshots/Polygon_fill.png deleted file mode 100644 index d4fc874e3b7..00000000000 Binary files a/__tests__/integration/snapshots/Polygon_fill.png and /dev/null differ diff --git a/__tests__/integration/snapshots/gallery_fujian.png b/__tests__/integration/snapshots/gallery_fujian.png new file mode 100644 index 00000000000..4d7251ee77e Binary files /dev/null and b/__tests__/integration/snapshots/gallery_fujian.png differ diff --git a/__tests__/integration/snapshots/gallery_variFlight.png b/__tests__/integration/snapshots/gallery_variFlight.png new file mode 100644 index 00000000000..a08a83d8379 Binary files /dev/null and b/__tests__/integration/snapshots/gallery_variFlight.png differ diff --git a/__tests__/integration/snapshots/heatmap_grid.png b/__tests__/integration/snapshots/heatmap_grid.png new file mode 100644 index 00000000000..6f2b9bd7837 Binary files /dev/null and b/__tests__/integration/snapshots/heatmap_grid.png differ diff --git a/__tests__/integration/snapshots/heatmap_hexagon.png b/__tests__/integration/snapshots/heatmap_hexagon.png new file mode 100644 index 00000000000..c9a391cacfb Binary files /dev/null and b/__tests__/integration/snapshots/heatmap_hexagon.png differ diff --git a/__tests__/integration/snapshots/heatmap_normal.png b/__tests__/integration/snapshots/heatmap_normal.png new file mode 100644 index 00000000000..579e4a7d892 Binary files /dev/null and b/__tests__/integration/snapshots/heatmap_normal.png differ diff --git a/__tests__/integration/snapshots/line_arc.png b/__tests__/integration/snapshots/line_arc.png new file mode 100644 index 00000000000..224f80431e1 Binary files /dev/null and b/__tests__/integration/snapshots/line_arc.png differ diff --git a/__tests__/integration/snapshots/line_arc3D.png b/__tests__/integration/snapshots/line_arc3D.png new file mode 100644 index 00000000000..32c4fe4ea1e Binary files /dev/null and b/__tests__/integration/snapshots/line_arc3D.png differ diff --git a/__tests__/integration/snapshots/line_flow.png b/__tests__/integration/snapshots/line_flow.png new file mode 100644 index 00000000000..cc6bb8fc812 Binary files /dev/null and b/__tests__/integration/snapshots/line_flow.png differ diff --git a/__tests__/integration/snapshots/line_greatcircle.png b/__tests__/integration/snapshots/line_greatcircle.png new file mode 100644 index 00000000000..a71a3e253d3 Binary files /dev/null and b/__tests__/integration/snapshots/line_greatcircle.png differ diff --git a/__tests__/integration/snapshots/line_normal.png b/__tests__/integration/snapshots/line_normal.png new file mode 100644 index 00000000000..08684beee17 Binary files /dev/null and b/__tests__/integration/snapshots/line_normal.png differ diff --git a/__tests__/integration/snapshots/line_simple.png b/__tests__/integration/snapshots/line_simple.png new file mode 100644 index 00000000000..20107b21bf4 Binary files /dev/null and b/__tests__/integration/snapshots/line_simple.png differ diff --git a/__tests__/integration/snapshots/line_wall.png b/__tests__/integration/snapshots/line_wall.png new file mode 100644 index 00000000000..95bdb86c5b2 Binary files /dev/null and b/__tests__/integration/snapshots/line_wall.png differ diff --git a/__tests__/integration/snapshots/mask_multi.png b/__tests__/integration/snapshots/mask_multi.png new file mode 100644 index 00000000000..3410a7fbe64 Binary files /dev/null and b/__tests__/integration/snapshots/mask_multi.png differ diff --git a/__tests__/integration/snapshots/mask_single.png b/__tests__/integration/snapshots/mask_single.png new file mode 100644 index 00000000000..e79fecf47f1 Binary files /dev/null and b/__tests__/integration/snapshots/mask_single.png differ diff --git a/__tests__/integration/snapshots/point_billboard.png b/__tests__/integration/snapshots/point_billboard.png new file mode 100644 index 00000000000..0f9894da37b Binary files /dev/null and b/__tests__/integration/snapshots/point_billboard.png differ diff --git a/__tests__/integration/snapshots/point_column.png b/__tests__/integration/snapshots/point_column.png new file mode 100644 index 00000000000..8cad08bf4d0 Binary files /dev/null and b/__tests__/integration/snapshots/point_column.png differ diff --git a/__tests__/integration/snapshots/point_fill.png b/__tests__/integration/snapshots/point_fill.png new file mode 100644 index 00000000000..d7359305ed7 Binary files /dev/null and b/__tests__/integration/snapshots/point_fill.png differ diff --git a/__tests__/integration/snapshots/point_fillImage.png b/__tests__/integration/snapshots/point_fillImage.png new file mode 100644 index 00000000000..44c9a6c8bab Binary files /dev/null and b/__tests__/integration/snapshots/point_fillImage.png differ diff --git a/__tests__/integration/snapshots/point_text.png b/__tests__/integration/snapshots/point_text.png new file mode 100644 index 00000000000..db769603af1 Binary files /dev/null and b/__tests__/integration/snapshots/point_text.png differ diff --git a/__tests__/integration/snapshots/polygon_extrude.png b/__tests__/integration/snapshots/polygon_extrude.png new file mode 100644 index 00000000000..0d1da4446e6 Binary files /dev/null and b/__tests__/integration/snapshots/polygon_extrude.png differ diff --git a/__tests__/integration/snapshots/polygon_extrusion.png b/__tests__/integration/snapshots/polygon_extrusion.png new file mode 100644 index 00000000000..3e537e3d297 Binary files /dev/null and b/__tests__/integration/snapshots/polygon_extrusion.png differ diff --git a/__tests__/integration/snapshots/polygon_fill.png b/__tests__/integration/snapshots/polygon_fill.png new file mode 100644 index 00000000000..a60552530d3 Binary files /dev/null and b/__tests__/integration/snapshots/polygon_fill.png differ diff --git a/__tests__/integration/utils/generator.ts b/__tests__/integration/utils/generator.ts index 3c7f48bcee3..eec536c9ab8 100644 --- a/__tests__/integration/utils/generator.ts +++ b/__tests__/integration/utils/generator.ts @@ -1,14 +1,14 @@ -import type { Browser, BrowserContext, Page } from 'playwright'; +import type { Browser, BrowserContext } from 'playwright'; import { chromium, devices } from 'playwright'; import { sleep } from './sleep'; import './useSnapshotMatchers'; export function generateCanvasTestCases( namespace: string, - tests: { name: string; sleepTime?: number; snapshots?: boolean }[], + tests: { name: string; sleepTime?: number; snapshot?: boolean }[], ) { const port = (globalThis as any).PORT; - let browser: Browser, context: BrowserContext, page: Page; + let browser: Browser, context: BrowserContext; beforeAll(async () => { // Setup @@ -16,8 +16,6 @@ export function generateCanvasTestCases( args: ['--headless', '--no-sandbox'], }); context = await browser.newContext(devices['Desktop Chrome']); - page = await context.newPage(); - await context.exposeFunction('screenshot', () => {}); }); afterAll(async () => { @@ -26,15 +24,29 @@ export function generateCanvasTestCases( }); tests - .filter((test) => test.snapshots !== false) + .filter((test) => test.snapshot !== false) .map((test) => { const { name, sleepTime = 200 } = test; const key = `${namespace}_${name}`; it(key, async () => { + const page = await context.newPage(); + + let resolveReady: () => void; + const readyPromise = new Promise((resolve) => { + resolveReady = () => { + resolve(); + }; + }); + + await page.exposeFunction('screenshot', async () => { + resolveReady(); + }); + // Go to test page served by vite devServer. - const url = `http://localhost:${port}/?type=${namespace}&name=${name}`; + const url = `http://localhost:${port}/?namespace=${namespace}&name=${name}&snapshot=true`; await page.goto(url); + await readyPromise; await sleep(sleepTime); // Chart already rendered, capture into buffer. @@ -45,7 +57,7 @@ export function generateCanvasTestCases( try { expect(buffer).toMatchCanvasSnapshot(dir, key, { maxError }); } finally { - // + page.close(); } }); }); diff --git a/__tests__/unit/preset/environment.ts b/__tests__/unit/preset/environment.ts index 4e023f37de5..6ee7506267d 100644 --- a/__tests__/unit/preset/environment.ts +++ b/__tests__/unit/preset/environment.ts @@ -1 +1,4 @@ (window as any).URL.createObjectURL = jest.fn; +(window as any).ResizeObserver = jest.fn().mockImplementation(() => ({ + observe: jest.fn(), +})); diff --git a/examples/constants.ts b/examples/constants.ts index 1e39a2f078e..f7011588789 100644 --- a/examples/constants.ts +++ b/examples/constants.ts @@ -1,18 +1,23 @@ -import type { RenderDemoMap, RenderDemoOptions } from './types'; +import type { GUIOptions, TestCaseBasemap } from './types'; -export const MAP_TYPES: RenderDemoMap[] = [ +export const DEFAULT_GUI_OPTIONS: GUIOptions = { + map: 'Map', + renderer: 'device', + animate: false, + enableWebGPU: false, +}; + +export const SEARCH_PARAMS_KEYS = ['namespace', 'name', 'snapshot'].concat( + Object.keys(DEFAULT_GUI_OPTIONS), +); + +export const MAP_TYPES: TestCaseBasemap[] = [ 'Map', 'GaodeMap', - 'BaiduMap', + 'Mapbox', 'MapLibre', + 'BaiduMap', 'TencentMap', - 'Mapbox', 'TMap', 'GoogleMap', ] as const; - -export const DEFAULT_RENDER_OPTIONS: RenderDemoOptions = { - map: 'Map', - renderer: 'device', - animate: false, -}; diff --git a/examples/data/globe-earthquake-mag.json b/examples/data/globe-earthquake-mag.json new file mode 100644 index 00000000000..7c1f7c11a7d --- /dev/null +++ b/examples/data/globe-earthquake-mag.json @@ -0,0 +1,6113 @@ +{ +"type": "FeatureCollection", +"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, +"features": [ +{ "type": "Feature", "properties": { "id": "ak16994521", "mag": 2.3, "time": 1507425650893, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.5129, 63.1016, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994519", "mag": 1.7, "time": 1507425289659, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.4048, 63.1224, 105.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994517", "mag": 1.6, "time": 1507424832518, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3597, 63.0781, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38021336", "mag": 1.42, "time": 1507423898710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.497, 34.299667, 7.64 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b2nn", "mag": 4.2, "time": 1507422626990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -87.6901, 12.0623, 46.41 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994510", "mag": 1.6, "time": 1507422449194, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.5053, 63.0719, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b2nb", "mag": 4.6, "time": 1507420784440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4576, -20.2873, 614.26 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994298", "mag": 2.4, "time": 1507419370097, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.789, 63.1725, 7.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905861", "mag": 1.39, "time": 1507418785100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.993164, 36.421833, 6.37 ] } }, +{ "type": "Feature", "properties": { "id": "ci38021304", "mag": 1.11, "time": 1507418426010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.0155, 33.656333, 12.37 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994293", "mag": 1.5, "time": 1507417256497, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.512, 63.0879, 10.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994287", "mag": 2.0, "time": 1507413903714, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4378, 63.0933, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994285", "mag": 1.5, "time": 1507413670029, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.6538, 63.2272, 96.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994283", "mag": 1.4, "time": 1507413587442, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.5325, 63.0844, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994280", "mag": 1.3, "time": 1507413266231, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.4752, 61.8518, 54.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994278", "mag": 1.8, "time": 1507413195076, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8597, 61.6214, 50.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994274", "mag": 1.9, "time": 1507412827617, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.7142, 62.9656, 93.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994273", "mag": 1.2, "time": 1507411925999, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2484, 61.2705, 69.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994270", "mag": 2.0, "time": 1507411814209, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.0732, 65.5942, 14.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b2ly", "mag": 4.1, "time": 1507411448780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -90.5445, 13.5146, 54.36 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905841", "mag": 1.38, "time": 1507411214450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.819504, 37.605499, 4.14 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905836", "mag": 1.4, "time": 1507410206440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.930168, 37.636833, -0.71 ] } }, +{ "type": "Feature", "properties": { "id": "ci38021272", "mag": 1.34, "time": 1507408122250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.509167, 34.1555, 16.34 ] } }, +{ "type": "Feature", "properties": { "id": "ci38021264", "mag": 1.0, "time": 1507407938100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.792167, 33.5115, 5.16 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993963", "mag": 1.4, "time": 1507407100665, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9126, 63.1812, 150.4 ] } }, +{ "type": "Feature", "properties": { "id": "hv61936851", "mag": 2.55, "time": 1507406278360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.078659, 19.374167, 2.15 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993960", "mag": 1.4, "time": 1507405129739, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3106, 61.5726, 26.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993952", "mag": 1.7, "time": 1507403679922, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5846, 60.2607, 34.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci38021224", "mag": 1.04, "time": 1507401391710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.929, 34.254833, 18.27 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993752", "mag": 1.3, "time": 1507401212982, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.5065, 63.0847, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993746", "mag": 1.3, "time": 1507399350671, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.8929, 63.5257, 3.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b2jk", "mag": 4.6, "time": 1507398878400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -175.7258, -18.9821, 195.22 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993741", "mag": 1.6, "time": 1507398797233, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3473, 63.0775, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905766", "mag": 2.64, "time": 1507397278960, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.137497, 36.579834, 7.72 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993738", "mag": 1.4, "time": 1507396778206, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1075, 61.8312, 71.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993736", "mag": 1.2, "time": 1507396542471, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3769, 63.0621, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b2ii", "mag": 4.3, "time": 1507395765330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.8319, 16.7195, 58.84 ] } }, +{ "type": "Feature", "properties": { "id": "uw61339006", "mag": 1.91, "time": 1507395622730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.689833, 47.049167, 5.38 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993732", "mag": 1.7, "time": 1507395602456, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.5283, 63.0785, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993720", "mag": 2.5, "time": 1507394741482, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.6683, 60.7696, 67.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993714", "mag": 1.6, "time": 1507394402896, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.7591, 61.6478, 30.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993710", "mag": 1.5, "time": 1507393418705, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3458, 63.0633, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993699", "mag": 1.6, "time": 1507392875390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4669, 63.0675, 3.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993695", "mag": 1.3, "time": 1507392837463, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.5169, 63.083, 1.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993692", "mag": 2.3, "time": 1507392657193, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4771, 63.0742, 4.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993486", "mag": 4.2, "time": 1507392435159, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.458, 63.1276, 14.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b2hz", "mag": 4.3, "time": 1507392287310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9686, 16.6087, 69.65 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905751", "mag": 1.21, "time": 1507391530870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.023666, 37.605335, 1.97 ] } }, +{ "type": "Feature", "properties": { "id": "ci38021056", "mag": 1.95, "time": 1507390783500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.793833, 33.493, 3.65 ] } }, +{ "type": "Feature", "properties": { "id": "ci38021048", "mag": 1.02, "time": 1507388708760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.225, 34.0335, 0.39 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993303", "mag": 1.9, "time": 1507385638408, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0033, 63.2623, 0.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b2hc", "mag": 4.9, "time": 1507385606770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.3179, -30.4302, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993301", "mag": 2.1, "time": 1507383291943, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.1913, 58.5727, 85.2 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251607", "mag": 3.09, "time": 1507383200950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -113.140503, 38.030666, 7.29 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905716", "mag": 1.07, "time": 1507382878240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.765663, 38.789166, 2.09 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905711", "mag": 1.17, "time": 1507382428800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.678001, 37.621498, 4.39 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993140", "mag": 1.9, "time": 1507381096302, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.8813, 63.1738, 75.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993128", "mag": 1.6, "time": 1507378828395, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.531, 61.7978, 14.8 ] } }, +{ "type": "Feature", "properties": { "id": "hv61936621", "mag": 1.98, "time": 1507378497820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.423492, 19.223499, 34.62 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993119", "mag": 1.5, "time": 1507378014192, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -138.8317, 59.7754, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905681", "mag": 1.39, "time": 1507377675100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.793999, 38.8255, 2.24 ] } }, +{ "type": "Feature", "properties": { "id": "hv61936531", "mag": 2.66, "time": 1507377140600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.32016, 19.338667, 4.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16992960", "mag": 1.9, "time": 1507376759252, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -158.4264, 67.7636, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16992953", "mag": 2.1, "time": 1507376626801, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.5725, 59.8372, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b2fz", "mag": 4.1, "time": 1507372645200, "felt": 103, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -71.7814, -32.4981, 23.29 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608370", "mag": 1.3, "time": 1507370926907, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.9711, 36.3094, 7.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16992628", "mag": 1.5, "time": 1507369548317, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -163.8046, 65.9499, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16992625", "mag": 1.4, "time": 1507369466929, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.8309, 63.376, 82.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905641", "mag": 1.22, "time": 1507368529650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.724167, 38.760334, 1.16 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b2fc", "mag": 5.1, "time": 1507368374110, "felt": 13, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -77.9778, -1.6647, 147.34 ] } }, +{ "type": "Feature", "properties": { "id": "ak16992611", "mag": 2.1, "time": 1507366872675, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.3324, 62.9966, 88.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16992607", "mag": 1.8, "time": 1507366536698, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.4858, 64.7593, 11.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b2et", "mag": 4.9, "time": 1507365487800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.7469, -33.0092, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16992603", "mag": 2.2, "time": 1507364931625, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.8133, 59.8473, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020960", "mag": 1.0, "time": 1507363084310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.673833, 33.904333, 35.76 ] } }, +{ "type": "Feature", "properties": { "id": "hv61936261", "mag": 1.72, "time": 1507362853030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.382172, 19.23, 34.41 ] } }, +{ "type": "Feature", "properties": { "id": "ak16992451", "mag": 1.8, "time": 1507362228460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.427, 66.3947, 5.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020944", "mag": 1.0, "time": 1507362158010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.457667, 34.326, 2.73 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259564", "mag": 1.03, "time": 1507361004730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.529833, 46.865833, 9.91 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905606", "mag": 1.19, "time": 1507358854330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.791832, 38.834835, 1.65 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608387", "mag": 1.0, "time": 1507358249243, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9071, 38.405, 11.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020896", "mag": 1.89, "time": 1507358144340, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.793833, 33.486833, 4.21 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b2dx", "mag": 4.5, "time": 1507357181260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 130.1291, -6.3628, 156.49 ] } }, +{ "type": "Feature", "properties": { "id": "se60208171", "mag": 2.4, "time": 1507353902490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -83.749833, 36.150333, 14.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905576", "mag": 1.77, "time": 1507352706600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.900833, 36.327168, 6.31 ] } }, +{ "type": "Feature", "properties": { "id": "ak16992147", "mag": 1.4, "time": 1507351430424, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0276, 62.5667, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16992146", "mag": 1.8, "time": 1507351047849, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -138.5063, 59.957, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905556", "mag": 1.77, "time": 1507350586140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.792, 38.834835, 1.77 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259559", "mag": 1.46, "time": 1507350177430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.530833, 46.869333, 10.71 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b2d1", "mag": 4.7, "time": 1507347862040, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -69.504, -16.7961, 178.13 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905531", "mag": 1.48, "time": 1507346675870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.831169, 37.4585, 2.53 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259549", "mag": 1.08, "time": 1507345321240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.516333, 46.8755, 11.43 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905521", "mag": 1.46, "time": 1507345267910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.816666, 37.603832, 4.04 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020824", "mag": 2.12, "time": 1507344823940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.655333, 34.632, 5.34 ] } }, +{ "type": "Feature", "properties": { "id": "ak16991857", "mag": 2.3, "time": 1507344587124, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.8808, 51.3254, 31.7 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608359", "mag": 1.1, "time": 1507344387447, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.1285, 37.4041, 0.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905511", "mag": 1.27, "time": 1507344302520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.817169, 37.604168, 4.02 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b2cx", "mag": 4.9, "time": 1507343887900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 69.1471, -23.7671, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905496", "mag": 1.94, "time": 1507341324260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.101166, 40.842499, 6.01 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b2cc", "mag": 5.0, "time": 1507340745260, "felt": null, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 132.668, 1.1151, 7.01 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020800", "mag": 1.46, "time": 1507340726000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.462667, 33.466333, 5.78 ] } }, +{ "type": "Feature", "properties": { "id": "ak16991706", "mag": 1.7, "time": 1507339655320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.2596, 60.2328, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16991711", "mag": 1.6, "time": 1507339653625, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.2013, 60.2021, 10.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16991704", "mag": 1.7, "time": 1507338343941, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.7575, 62.4396, 50.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16991697", "mag": 2.1, "time": 1507336466527, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.3178, 60.5797, 88.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020768", "mag": 1.56, "time": 1507336119080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.460167, 34.3335, 2.89 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020760", "mag": 1.22, "time": 1507335982510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.468167, 34.333167, 2.87 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020752", "mag": 1.81, "time": 1507335765850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.793, 33.490333, 4.58 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020744", "mag": 1.76, "time": 1507335646140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.566333, 35.339667, 7.86 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b2c0", "mag": 5.3, "time": 1507335391250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.3171, -33.0297, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905461", "mag": 1.16, "time": 1507333007350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.795998, 38.826, 2.32 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608334", "mag": 1.1, "time": 1507331333919, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.1247, 37.3789, 8.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16991557", "mag": 1.4, "time": 1507331263084, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.2293, 64.9749, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b2ba", "mag": 4.4, "time": 1507331102840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 152.3636, -10.0109, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b2b9", "mag": 4.2, "time": 1507331091160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 73.3529, 39.6124, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16991437", "mag": 2.0, "time": 1507330383962, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.4583, 60.3395, 72.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b2av", "mag": 4.3, "time": 1507329021540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 138.9649, 43.0121, 217.94 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608329", "mag": 1.3, "time": 1507328136999, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.1198, 37.3861, 8.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020720", "mag": 1.45, "time": 1507327306610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.955667, 34.34, -0.29 ] } }, +{ "type": "Feature", "properties": { "id": "uw61338531", "mag": 1.37, "time": 1507326914640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.991667, 46.572333, -0.3 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608354", "mag": 1.0, "time": 1507326343697, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.747, 39.8477, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905451", "mag": 1.47, "time": 1507326329600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.753833, 39.8485, 6.72 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905441", "mag": 1.23, "time": 1507325408690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.127, 36.566667, 9.16 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b29t", "mag": 4.5, "time": 1507325144410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 145.6471, 17.7456, 196.33 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b2ab", "mag": 2.6, "time": 1507324395860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -108.8949, 32.7663, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905436", "mag": 1.41, "time": 1507323505830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.155667, 36.5565, 6.94 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020712", "mag": 1.19, "time": 1507323492150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.991, 32.578667, 2.62 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b289", "mag": 2.4, "time": 1507321230800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.7321, 36.481, 5.37 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905431", "mag": 1.0, "time": 1507321021480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.178833, 38.107, -0.02 ] } }, +{ "type": "Feature", "properties": { "id": "ak16991182", "mag": 1.0, "time": 1507320721326, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.1644, 62.2007, 15.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16991178", "mag": 1.8, "time": 1507320357991, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5804, 63.1717, 121.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905426", "mag": 1.24, "time": 1507320241050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.688667, 37.5335, 6.91 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020680", "mag": 1.5, "time": 1507320090270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.516, 33.860833, 0.62 ] } }, +{ "type": "Feature", "properties": { "id": "ak16991069", "mag": 1.8, "time": 1507318145350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.6965, 59.7754, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b27a", "mag": 2.4, "time": 1507317641850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.2269, 36.6265, 5.07 ] } }, +{ "type": "Feature", "properties": { "id": "ak16991058", "mag": 2.6, "time": 1507317554328, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.3172, 63.6837, 3.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020656", "mag": 1.03, "time": 1507317548410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.646667, 36.148333, 0.93 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020648", "mag": 1.08, "time": 1507317476900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.1915, 35.0025, -0.87 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905416", "mag": 1.19, "time": 1507317386760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.803333, 37.457667, -0.31 ] } }, +{ "type": "Feature", "properties": { "id": "uw61338426", "mag": 1.65, "time": 1507316609360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.7105, 43.553333, 7.02 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259489", "mag": 1.66, "time": 1507316359200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.477167, 45.9945, -2.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020624", "mag": 1.22, "time": 1507316271630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.362, 32.941333, 10.15 ] } }, +{ "type": "Feature", "properties": { "id": "ak16991011", "mag": 2.0, "time": 1507315584886, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.9279, 62.7834, 4.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b26p", "mag": 4.7, "time": 1507315424010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 68.9568, -49.2119, 13.54 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251447", "mag": 2.18, "time": 1507314096180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.457, 42.633167, 4.91 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905411", "mag": 1.24, "time": 1507313481610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.962333, 37.920333, -0.33 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b260", "mag": 4.4, "time": 1507311862190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 86.7487, 30.0165, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020552", "mag": 1.28, "time": 1507311788210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.351667, 35.052833, -1.01 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b25h", "mag": 5.5, "time": 1507311683180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -15.5503, -35.3171, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990870", "mag": 1.8, "time": 1507310931075, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.9372, 62.1214, 48.9 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608306", "mag": 1.9, "time": 1507310059424, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.6177, 38.5802, 5.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b24c", "mag": 4.6, "time": 1507309684550, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 143.7841, 37.4191, 31.5 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259479", "mag": 1.25, "time": 1507309316470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5305, 46.867167, 12.62 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251412", "mag": 2.1, "time": 1507308318150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.460333, 42.602667, 6.75 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905346", "mag": 2.33, "time": 1507308237260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.803333, 37.457333, 0.99 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020512", "mag": 1.61, "time": 1507308155060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.2815, 35.633833, 6.15 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020480", "mag": 1.04, "time": 1507307612510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.314167, 34.0145, 2.75 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990671", "mag": 1.6, "time": 1507307067130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.0099, 66.2332, 1.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905326", "mag": 1.17, "time": 1507305678060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.706, 38.783667, 2.5 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259459", "mag": 0.95, "time": 1507305300890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5315, 46.8575, 12.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020408", "mag": 1.2, "time": 1507302977930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.019833, 33.876, -0.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990501", "mag": 2.8, "time": 1507302735109, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2441, 60.1679, 148.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b20f", "mag": 5.4, "time": 1507301800580, "felt": 169, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 141.1969, 37.0997, 47.42 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990465", "mag": 1.7, "time": 1507301707708, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.519, 67.5663, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020392", "mag": 2.6, "time": 1507301676460, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.894167, 31.614, 5.89 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990463", "mag": 1.6, "time": 1507300956103, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.1925, 59.8037, 20.0 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251397", "mag": 1.18, "time": 1507300478100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.436333, 42.554833, 9.68 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608296", "mag": 1.1, "time": 1507299948387, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.9267, 39.4223, 8.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020376", "mag": 1.4, "time": 1507299919340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.476667, 35.752167, 2.24 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608295", "mag": 2.0, "time": 1507298898804, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9217, 38.4131, 8.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b1zv", "mag": 5.1, "time": 1507298433140, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 95.0977, 12.0039, 21.82 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990379", "mag": 2.0, "time": 1507296668722, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.4456, 63.3167, 112.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990317", "mag": 2.4, "time": 1507295355033, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.6485, 60.9026, 21.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905256", "mag": 1.69, "time": 1507295344860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7755, 38.805167, 0.72 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020296", "mag": 0.98, "time": 1507294899000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.445, 34.226167, 12.35 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905246", "mag": 1.14, "time": 1507294685610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.797333, 38.813499, 2.36 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905241", "mag": 1.27, "time": 1507294429860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.806167, 38.822333, 1.56 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990306", "mag": 1.6, "time": 1507293337500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.164, 63.5211, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905231", "mag": 1.31, "time": 1507293268040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.600333, 38.771667, 0.05 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259449", "mag": 1.29, "time": 1507293189490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.557667, 46.894167, 9.91 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905226", "mag": 1.25, "time": 1507291334810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.798333, 37.565333, -0.35 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020256", "mag": 2.0, "time": 1507290973570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.757833, 34.172833, 6.62 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020240", "mag": 1.05, "time": 1507290356170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.355667, 35.822833, 16.75 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b1xz", "mag": 5.2, "time": 1507289341850, "felt": null, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 155.9405, -6.8684, 106.51 ] } }, +{ "type": "Feature", "properties": { "id": "uw61338256", "mag": 1.22, "time": 1507287741010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.509333, 45.6895, 9.57 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020232", "mag": 1.4, "time": 1507287412090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.8455, 34.000333, 9.47 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259444", "mag": 1.6, "time": 1507286758530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.5795, 44.259167, 3.88 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259434", "mag": 1.18, "time": 1507286693390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.322167, 43.681333, 9.95 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990167", "mag": 3.0, "time": 1507285562299, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.2949, 51.2318, 28.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990162", "mag": 3.2, "time": 1507285408267, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.0402, 65.2966, 0.1 ] } }, +{ "type": "Feature", "properties": { "id": "hv61935226", "mag": 1.78, "time": 1507284229580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.42366, 19.2805, 7.76 ] } }, +{ "type": "Feature", "properties": { "id": "hv61935131", "mag": 1.67, "time": 1507283791470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.248833, 18.876833, 12.183 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990109", "mag": 1.9, "time": 1507282869514, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1519, 63.251, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b1xd", "mag": 4.4, "time": 1507281825250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 119.9639, -0.4925, 44.07 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990102", "mag": 1.6, "time": 1507281420124, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7545, 61.5105, 70.6 ] } }, +{ "type": "Feature", "properties": { "id": "hv61935091", "mag": 2.94, "time": 1507279304370, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.2205, 19.380333, 14.051 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608291", "mag": 1.6, "time": 1507279195578, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.2224, 39.4096, 5.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905186", "mag": 0.99, "time": 1507278858510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8245, 37.483833, 5.31 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b1v8", "mag": 6.0, "time": 1507276773110, "felt": 108, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 143.9537, 37.485, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251377", "mag": 1.43, "time": 1507274976970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.444, 42.660667, 5.95 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989976", "mag": 3.1, "time": 1507274375943, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.7235, 59.8808, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259414", "mag": 1.86, "time": 1507273645130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.997833, 47.455667, 1.73 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b1v0", "mag": 4.7, "time": 1507273552100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 146.6145, 13.8504, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989973", "mag": 1.3, "time": 1507272833815, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.7833, 64.8537, 19.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b2dh", "mag": 3.3, "time": 1507270603000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.92, 49.06, 22.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989967", "mag": 1.9, "time": 1507270303410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.3206, 61.7195, 41.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020152", "mag": 1.08, "time": 1507270230410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.557333, 32.948833, 3.78 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b1um", "mag": 2.7, "time": 1507269804040, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4493, 42.6517, 7.67 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905156", "mag": 1.79, "time": 1507269478010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.801167, 38.822, 2.67 ] } }, +{ "type": "Feature", "properties": { "id": "nc71107634", "mag": 1.13, "time": 1507269413290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.478167, 38.6015, 12.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b1un", "mag": 4.3, "time": 1507269388630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 178.4985, 51.6139, 71.76 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251357", "mag": 1.47, "time": 1507268672130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.455333, 42.652833, 2.92 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989960", "mag": 1.1, "time": 1507268319981, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.2116, 64.2744, 14.8 ] } }, +{ "type": "Feature", "properties": { "id": "hv61935031", "mag": 1.75, "time": 1507267817920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.428833, 19.329, 10.185 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905151", "mag": 1.08, "time": 1507267299070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.823167, 37.607, 4.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259404", "mag": 1.03, "time": 1507266753410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.532167, 46.873, 11.23 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b1u8", "mag": 4.6, "time": 1507265974560, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -64.1261, -17.5702, 36.33 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020112", "mag": 1.06, "time": 1507265623210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.434833, 33.0315, 3.46 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905146", "mag": 1.56, "time": 1507265461960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7915, 38.8195, 1.42 ] } }, +{ "type": "Feature", "properties": { "id": "uw61338091", "mag": 1.62, "time": 1507265317630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.2, 47.583333, 23.03 ] } }, +{ "type": "Feature", "properties": { "id": "uw61338086", "mag": 1.33, "time": 1507265080940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.200333, 47.583833, 23.12 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251347", "mag": 1.61, "time": 1507264823080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.494833, 42.639667, 0.79 ] } }, +{ "type": "Feature", "properties": { "id": "nc71107639", "mag": 1.32, "time": 1507263429870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.9235, 39.599833, 20.91 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905131", "mag": 1.06, "time": 1507263391130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.831, 37.5295, 5.95 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905121", "mag": 1.41, "time": 1507263129660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.403, 38.364167, 8.42 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b1tr", "mag": 4.8, "time": 1507262599510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 151.9528, -10.3953, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989915", "mag": 1.5, "time": 1507260314998, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3718, 63.0764, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "uw61338061", "mag": 1.26, "time": 1507260032120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.744833, 47.490167, 16.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989910", "mag": 2.1, "time": 1507259762026, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.6057, 63.4194, 106.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905106", "mag": 1.0, "time": 1507258246340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.822, 38.814833, 1.61 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905101", "mag": 2.97, "time": 1507257072490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -125.777167, 41.2375, 7.51 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989906", "mag": 1.6, "time": 1507256091995, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.063, 65.8813, 12.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020032", "mag": 1.89, "time": 1507255962830, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.7975, 33.5, 5.36 ] } }, +{ "type": "Feature", "properties": { "id": "ci38020024", "mag": 1.53, "time": 1507255628970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.875167, 33.957, 3.47 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b1t0", "mag": 4.8, "time": 1507255428530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -25.496, 0.9934, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b1sv", "mag": 4.6, "time": 1507253577740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 152.1867, -9.9486, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251342", "mag": 1.12, "time": 1507252828550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.414167, 42.5485, 6.65 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905066", "mag": 0.98, "time": 1507251331760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9395, 37.636, 5.66 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608277", "mag": 1.5, "time": 1507251023072, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.857, 37.3396, 3.9 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251327", "mag": 1.16, "time": 1507250350380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.672333, 39.4485, 12.04 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989868", "mag": 1.6, "time": 1507249990990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.6081, 61.1327, 14.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci38019984", "mag": 1.38, "time": 1507249506910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.598667, 33.450667, 7.77 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608273", "mag": 1.0, "time": 1507249499810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.0539, 37.1082, 8.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci38019976", "mag": 1.92, "time": 1507249308880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.377167, 34.427, 9.46 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b1s9", "mag": 4.0, "time": 1507248914000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -71.348, -29.925, 48.8 ] } }, +{ "type": "Feature", "properties": { "id": "uw61337986", "mag": 1.12, "time": 1507245979370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.395167, 45.685667, -0.74 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905011", "mag": 2.81, "time": 1507244867710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8105, 37.472, 6.12 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905016", "mag": 1.36, "time": 1507244847860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7825, 38.7915, 0.56 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259379", "mag": 0.99, "time": 1507244598420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.529, 46.871167, 12.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989827", "mag": 1.4, "time": 1507244539965, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.2289, 64.9761, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989825", "mag": 1.8, "time": 1507243916881, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1245, 62.4971, 81.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905001", "mag": 1.65, "time": 1507243472580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.808, 38.822, 1.64 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904996", "mag": 2.14, "time": 1507243164460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.588667, 40.652333, 25.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989822", "mag": 1.5, "time": 1507242888109, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.857, 61.9122, 45.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b1rh", "mag": 4.6, "time": 1507242807430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 144.6063, 21.8848, 100.39 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989815", "mag": 2.5, "time": 1507240652193, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.192, 61.0044, 106.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989811", "mag": 1.8, "time": 1507240498324, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.939, 62.7658, 79.9 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251317", "mag": 1.66, "time": 1507240484300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.418167, 42.544333, 6.24 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b1px", "mag": 2.6, "time": 1507239146260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4355, 42.5495, 8.32 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259359", "mag": 1.17, "time": 1507238290040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.965, 43.357333, 5.92 ] } }, +{ "type": "Feature", "properties": { "id": "uw61337951", "mag": 2.3, "time": 1507238213550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.549833, 49.328833, -0.06 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989718", "mag": 1.4, "time": 1507237904044, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.5289, 61.2012, 0.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989717", "mag": 1.9, "time": 1507237796189, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.701, 59.032, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "uw61337946", "mag": 2.27, "time": 1507237659430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.817167, 47.392167, -0.46 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904961", "mag": 0.97, "time": 1507237420050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8365, 37.482833, 1.23 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989714", "mag": 1.7, "time": 1507235850265, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0124, 65.8954, 7.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci38019864", "mag": 1.0, "time": 1507235571440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.794167, 33.508667, 6.47 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259334", "mag": 1.45, "time": 1507235042560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.525667, 46.872833, 11.13 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989709", "mag": 1.6, "time": 1507234798667, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.3071, 63.3209, 6.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989702", "mag": 2.5, "time": 1507234198600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.414, 63.3343, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989701", "mag": 1.8, "time": 1507234162044, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0004, 65.8966, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989699", "mag": 1.7, "time": 1507234036518, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.6575, 60.1339, 106.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904941", "mag": 1.63, "time": 1507233857390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.810167, 38.8205, 2.04 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904936", "mag": 3.14, "time": 1507233758820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -127.192, 40.163167, 11.62 ] } }, +{ "type": "Feature", "properties": { "id": "hv61934246", "mag": 1.02, "time": 1507233403750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.289833, 19.374, 1.772 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989698", "mag": 1.7, "time": 1507233388591, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0126, 65.8742, 0.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989695", "mag": 1.9, "time": 1507232812188, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9865, 65.9098, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904926", "mag": 1.29, "time": 1507232594330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.837167, 37.504167, 0.07 ] } }, +{ "type": "Feature", "properties": { "id": "ci38019816", "mag": 1.31, "time": 1507231819600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.491, 33.846167, -0.48 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904891", "mag": 1.41, "time": 1507229918140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.104833, 37.324833, -0.31 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989694", "mag": 1.5, "time": 1507229700025, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.7663, 63.5209, 14.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904886", "mag": 2.03, "time": 1507229279930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.3835, 40.709833, 19.57 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989692", "mag": 1.6, "time": 1507228866480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0051, 65.8735, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904881", "mag": 1.48, "time": 1507228723050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.194667, 40.598333, 15.65 ] } }, +{ "type": "Feature", "properties": { "id": "ci38019744", "mag": 1.44, "time": 1507226134710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.072333, 33.020667, -0.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989683", "mag": 2.4, "time": 1507225956631, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.785, 60.8774, 34.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci38019728", "mag": 1.0, "time": 1507225418070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.720667, 36.004, 2.64 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904846", "mag": 1.87, "time": 1507224165330, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.8105, 38.821167, 1.64 ] } }, +{ "type": "Feature", "properties": { "id": "hv61934126", "mag": 1.58, "time": 1507223732510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.252167, 18.903833, 12.692 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989680", "mag": 2.5, "time": 1507223654781, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -163.5871, 67.3896, 1.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989626", "mag": 1.5, "time": 1507223506919, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1613, 62.9421, 105.5 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251267", "mag": 1.3, "time": 1507222702710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.711, 37.088833, 8.72 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251262", "mag": 2.09, "time": 1507221444340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.413167, 42.600333, 6.09 ] } }, +{ "type": "Feature", "properties": { "id": "hv61934021", "mag": 1.71, "time": 1507221215150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.600174, 19.477667, 2.61 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259309", "mag": 0.99, "time": 1507220291830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.4755, 46.855833, 10.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904766", "mag": 1.2, "time": 1507219571830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.817667, 37.607833, 4.46 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b1ip", "mag": 4.3, "time": 1507219416430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 127.6953, -3.0506, 46.98 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989556", "mag": 1.8, "time": 1507219027423, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.1068, 64.723, 3.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904761", "mag": 1.28, "time": 1507218469040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.786667, 35.167, 4.77 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989554", "mag": 1.8, "time": 1507217831958, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.9487, 67.1103, 6.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38019560", "mag": 1.18, "time": 1507217071900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.2355, 35.399833, 11.83 ] } }, +{ "type": "Feature", "properties": { "id": "ld60143826", "mag": 1.25, "time": 1507215008870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -75.237833, 44.094, 4.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904741", "mag": 1.17, "time": 1507213799120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.883667, 37.539333, 2.63 ] } }, +{ "type": "Feature", "properties": { "id": "uw61314897", "mag": 1.26, "time": 1507213038640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.924167, 46.832167, 9.6 ] } }, +{ "type": "Feature", "properties": { "id": "hv61933821", "mag": 2.22, "time": 1507211808310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.427667, 19.767167, 23.499 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259289", "mag": 1.11, "time": 1507209951340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.482833, 46.8195, 2.22 ] } }, +{ "type": "Feature", "properties": { "id": "ci38019464", "mag": 2.55, "time": 1507209518050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.010667, 33.179667, 8.09 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251247", "mag": 1.23, "time": 1507208707300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.086833, 44.772167, 11.73 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989517", "mag": 1.3, "time": 1507208506436, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3491, 63.087, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38019448", "mag": 1.15, "time": 1507207944620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.294333, 34.679333, 2.44 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989485", "mag": 1.9, "time": 1507207780001, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -159.6654, 67.5326, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904706", "mag": 1.66, "time": 1507207659710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.798167, 38.793833, 3.66 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989482", "mag": 1.4, "time": 1507206716138, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.4807, 64.7367, 8.7 ] } }, +{ "type": "Feature", "properties": { "id": "uw61314867", "mag": 1.16, "time": 1507206461330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.192333, 47.183667, 14.42 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989481", "mag": 2.6, "time": 1507206068023, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.1435, 51.4576, 12.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904681", "mag": 2.64, "time": 1507204013350, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.8035, 38.791333, 3.29 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b1f7", "mag": 5.0, "time": 1507202248310, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 126.4874, 7.3643, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259279", "mag": 1.25, "time": 1507201170830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.476333, 44.006167, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989448", "mag": 1.0, "time": 1507200035021, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.9384, 64.5888, 18.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b1dj", "mag": 4.7, "time": 1507198268580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 49.1899, 31.277, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259274", "mag": 1.3, "time": 1507198163850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.318333, 46.1425, 12.9 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259269", "mag": 2.63, "time": 1507197824690, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.317333, 46.126333, 14.98 ] } }, +{ "type": "Feature", "properties": { "id": "ci38019328", "mag": 2.0, "time": 1507197738510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.290167, 34.678, 2.65 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b1da", "mag": 4.5, "time": 1507196589420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 178.5051, -25.068, 564.41 ] } }, +{ "type": "Feature", "properties": { "id": "ci38019312", "mag": 1.27, "time": 1507196570560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.412333, 35.621833, 7.71 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259264", "mag": 1.58, "time": 1507195834720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.989667, 43.0535, 5.98 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989416", "mag": 1.9, "time": 1507192569868, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.8165, 59.7884, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259259", "mag": 1.73, "time": 1507192054540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.3, 46.1355, 13.17 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989388", "mag": 2.2, "time": 1507191783280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.8358, 59.8781, 1.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b1c3", "mag": 5.4, "time": 1507191096920, "felt": 5, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -68.5742, -22.4118, 112.87 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904646", "mag": 2.52, "time": 1507190856940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.472, 40.616833, 21.52 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989386", "mag": 1.8, "time": 1507190760834, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.611, 63.1832, 11.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci37167708", "mag": 1.38, "time": 1507190349370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.7095, 33.2065, 10.46 ] } }, +{ "type": "Feature", "properties": { "id": "hv61933706", "mag": 1.21, "time": 1507190060680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.2125, 19.363, 1.776 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904641", "mag": 1.23, "time": 1507189755650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.236667, 37.334333, 8.36 ] } }, +{ "type": "Feature", "properties": { "id": "ci38019264", "mag": 1.99, "time": 1507188934660, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.2315, 32.416667, 18.41 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251227", "mag": 1.34, "time": 1507188766440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.442667, 42.578833, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259244", "mag": 1.28, "time": 1507188159830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.527833, 46.866167, 12.04 ] } }, +{ "type": "Feature", "properties": { "id": "hv61933701", "mag": 2.09, "time": 1507187842930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.470673, 19.211, 37.73 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904626", "mag": 0.96, "time": 1507187453970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.572333, 39.013167, -0.67 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251207", "mag": 1.35, "time": 1507187087800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.301167, 39.1075, 2.75 ] } }, +{ "type": "Feature", "properties": { "id": "ci38019256", "mag": 2.06, "time": 1507186145760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.372167, 33.358833, 11.42 ] } }, +{ "type": "Feature", "properties": { "id": "ci38019248", "mag": 1.49, "time": 1507186142240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.366, 33.357667, 11.67 ] } }, +{ "type": "Feature", "properties": { "id": "uw61314807", "mag": 1.16, "time": 1507185870880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.191167, 47.179833, 15.66 ] } }, +{ "type": "Feature", "properties": { "id": "se60045413", "mag": 1.81, "time": 1507185703120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -83.742167, 35.985167, 18.08 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904601", "mag": 0.95, "time": 1507185126040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.819, 37.603333, 3.65 ] } }, +{ "type": "Feature", "properties": { "id": "ci38019240", "mag": 1.25, "time": 1507185093960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.394, 35.618833, 8.88 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989380", "mag": 1.9, "time": 1507184561453, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3822, 60.6535, 53.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989379", "mag": 1.0, "time": 1507183395241, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.2677, 63.314, 4.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci38019200", "mag": 1.99, "time": 1507181070780, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.806833, 36.043833, 1.22 ] } }, +{ "type": "Feature", "properties": { "id": "ci38019192", "mag": 1.69, "time": 1507180426220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.807333, 36.043167, 1.21 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904556", "mag": 1.22, "time": 1507178909260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7625, 38.821667, 1.49 ] } }, +{ "type": "Feature", "properties": { "id": "ci38019184", "mag": 1.33, "time": 1507178811140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.319833, 33.886333, 15.24 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989373", "mag": 2.2, "time": 1507178319160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0253, 59.7752, 99.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989370", "mag": 2.0, "time": 1507178108703, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9621, 62.3999, 67.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc71107619", "mag": 2.37, "time": 1507175814060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.793167, 38.814333, 3.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904521", "mag": 2.61, "time": 1507175806240, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.792, 38.813833, 3.02 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989344", "mag": 1.8, "time": 1507174164228, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.5816, 59.9877, 48.6 ] } }, +{ "type": "Feature", "properties": { "id": "uw61314692", "mag": 1.1, "time": 1507174062970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.048833, 48.836333, 3.53 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259229", "mag": 1.6, "time": 1507174016680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.526667, 46.874333, 12.15 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251182", "mag": 2.38, "time": 1507172461010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.415167, 42.5495, 8.84 ] } }, +{ "type": "Feature", "properties": { "id": "ci38019104", "mag": 1.08, "time": 1507172395710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.846167, 33.711167, 14.99 ] } }, +{ "type": "Feature", "properties": { "id": "uw61314677", "mag": 1.65, "time": 1507171780320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.027667, 48.845833, 0.9 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251177", "mag": 1.51, "time": 1507171597620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.880667, 37.041, 17.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904476", "mag": 1.12, "time": 1507171050970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7565, 38.782501, 0.82 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904471", "mag": 1.34, "time": 1507170987390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.753167, 38.775667, 1.61 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989336", "mag": 1.2, "time": 1507169863981, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2568, 63.5162, 8.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904466", "mag": 1.16, "time": 1507169797040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.808667, 37.467667, 1.31 ] } }, +{ "type": "Feature", "properties": { "id": "ci37167548", "mag": 1.21, "time": 1507169669520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.3645, 33.350667, 11.33 ] } }, +{ "type": "Feature", "properties": { "id": "ci38019080", "mag": 1.35, "time": 1507169663590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.3545, 33.3525, 12.25 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989295", "mag": 4.3, "time": 1507169038804, "felt": 3, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ -152.901, 58.3623, 46.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci38019056", "mag": 2.12, "time": 1507167035520, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.805167, 36.042, 1.36 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989291", "mag": 1.7, "time": 1507165460879, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.1162, 61.3056, 37.1 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608181", "mag": 1.2, "time": 1507165236408, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.7192, 37.7977, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b190", "mag": 2.6, "time": 1507164698800, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.7663, 36.4461, 6.31 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989285", "mag": 2.3, "time": 1507164594638, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5337, 60.8331, 35.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018992", "mag": 1.21, "time": 1507164594280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.435667, 33.033167, 6.13 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905406", "mag": 1.37, "time": 1507163603630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.975, 40.912333, 6.11 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989282", "mag": 2.6, "time": 1507162971426, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.8816, 53.7666, 69.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b185", "mag": 3.4, "time": 1507162321850, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.755, 36.45, 7.23 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018976", "mag": 1.34, "time": 1507162296820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.6665, 33.961333, 15.54 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904421", "mag": 1.81, "time": 1507162198800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -124.311667, 40.594833, 17.71 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989280", "mag": 2.0, "time": 1507162092700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -162.2549, 67.5542, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259214", "mag": 1.11, "time": 1507161815690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.529, 46.873667, 10.6 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608178", "mag": 1.2, "time": 1507161066465, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.8195, 37.303, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018944", "mag": 1.13, "time": 1507160279190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.801333, 36.0425, 0.57 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018936", "mag": 1.06, "time": 1507160033160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.352833, 33.1335, 7.01 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018928", "mag": 0.95, "time": 1507159919230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.758833, 33.67, 13.89 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989265", "mag": 2.4, "time": 1507159550480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7536, 62.8345, 98.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989262", "mag": 1.2, "time": 1507158170981, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.4466, 64.9696, 1.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989256", "mag": 2.1, "time": 1507157336866, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3316, 62.6072, 87.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b16h", "mag": 4.5, "time": 1507156394080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -66.7169, -23.9861, 195.32 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259199", "mag": 1.02, "time": 1507156049410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.531, 46.862667, 9.74 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989147", "mag": 1.8, "time": 1507155523233, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.2126, 62.1419, 50.6 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259194", "mag": 2.1, "time": 1507155343850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.326833, 46.116, 15.12 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b15z", "mag": 3.5, "time": 1507154804460, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.7425, 36.4507, 4.85 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989143", "mag": 1.6, "time": 1507154781579, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2414, 61.1185, 60.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018808", "mag": 0.95, "time": 1507153541570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.803667, 36.042, 1.12 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259184", "mag": 2.43, "time": 1507153540560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.529, 46.875, 11.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018800", "mag": 1.11, "time": 1507153075770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.805667, 36.044667, 1.33 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904366", "mag": 2.17, "time": 1507152989540, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.821833, 37.603167, 4.37 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904361", "mag": 2.03, "time": 1507152804460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.802, 38.819667, 3.31 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018776", "mag": 1.23, "time": 1507152409830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.796667, 33.506833, 4.99 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018760", "mag": 1.23, "time": 1507152333150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.805333, 36.044167, 1.08 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018752", "mag": 1.02, "time": 1507152229710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.803833, 36.0435, 1.58 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904356", "mag": 1.39, "time": 1507151361960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.986333, 37.451833, 11.44 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b152", "mag": 4.2, "time": 1507151144560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5193, 15.6807, 43.81 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259179", "mag": 1.09, "time": 1507150593920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.249667, 45.922167, -2.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608141", "mag": 1.4, "time": 1507150245096, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.5709, 37.2677, 5.8 ] } }, +{ "type": "Feature", "properties": { "id": "uw61314607", "mag": 2.13, "time": 1507149876900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.029167, 48.8415, 0.56 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989132", "mag": 3.2, "time": 1507149758758, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.904, 54.6732, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018704", "mag": 1.42, "time": 1507149228410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.937167, 32.9105, -0.2 ] } }, +{ "type": "Feature", "properties": { "id": "hv61932706", "mag": 2.34, "time": 1507148766410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.0805, 19.384667, 3.233 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018696", "mag": 1.43, "time": 1507148649160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.469333, 33.481, 7.42 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018688", "mag": 1.23, "time": 1507148125030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.7775, 34.859167, -1.14 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989124", "mag": 2.3, "time": 1507147085613, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.9048, 62.8046, 5.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989120", "mag": 1.9, "time": 1507146960353, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.3904, 61.7684, 33.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904326", "mag": 1.4, "time": 1507146844270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.835, 37.6255, 3.28 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018648", "mag": 1.34, "time": 1507146046240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.282833, 33.307, 10.02 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b12w", "mag": 4.1, "time": 1507145834470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -108.5682, 23.7468, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "uw61314577", "mag": 2.31, "time": 1507145284260, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -124.101667, 47.519667, 24.66 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989116", "mag": 2.0, "time": 1507144999479, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9792, 59.2967, 30.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904301", "mag": 1.44, "time": 1507144400690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.590333, 37.9535, 3.71 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904291", "mag": 0.97, "time": 1507144116270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.807335, 38.823166, 0.51 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018592", "mag": 0.98, "time": 1507144088190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.191, 34.995667, -0.84 ] } }, +{ "type": "Feature", "properties": { "id": "nc71107609", "mag": 1.42, "time": 1507143933230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8315, 37.459167, 2.81 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904286", "mag": 2.01, "time": 1507143903920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.127667, 36.540667, 3.02 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259164", "mag": 1.54, "time": 1507143801870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.466667, 46.003833, -2.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989114", "mag": 1.5, "time": 1507143799499, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2987, 62.9001, 136.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904276", "mag": 2.19, "time": 1507143670520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.125833, 36.539667, 3.42 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989112", "mag": 1.5, "time": 1507143346025, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.9517, 60.4284, 76.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989109", "mag": 1.6, "time": 1507142888288, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.4575, 68.4924, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us1000alvi", "mag": 4.8, "time": 1507142880510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 69.2314, -22.7343, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b11q", "mag": 4.3, "time": 1507142721780, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -95.0179, 16.6332, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608130", "mag": 2.0, "time": 1507142028227, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.6247, 38.6437, 2.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018568", "mag": 1.17, "time": 1507141815580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.480167, 33.8245, -0.64 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904241", "mag": 1.13, "time": 1507141805960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.843333, 37.550333, -1.19 ] } }, +{ "type": "Feature", "properties": { "id": "nc71107614", "mag": 1.26, "time": 1507141794500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.9105, 37.975, 2.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904226", "mag": 1.44, "time": 1507141566380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.839167, 37.554167, -0.37 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904231", "mag": 0.95, "time": 1507141526700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.848, 37.565167, -0.65 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989106", "mag": 1.6, "time": 1507141095901, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5043, 63.2003, 100.7 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608125", "mag": 1.1, "time": 1507140434096, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.0698, 39.2152, 9.9 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251107", "mag": 2.02, "time": 1507140276970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.438667, 42.623, -0.06 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989101", "mag": 1.7, "time": 1507139784743, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.7521, 62.788, 15.0 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70236238", "mag": 1.83, "time": 1507139648960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.036, 37.001167, 5.77 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018464", "mag": 0.95, "time": 1507138418030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.469667, 34.0245, -0.75 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904196", "mag": 1.0, "time": 1507136805190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.407833, 36.764667, 10.33 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989095", "mag": 1.5, "time": 1507135541282, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.2816, 62.4313, 44.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018408", "mag": 1.57, "time": 1507134824880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.797167, 33.499, 4.25 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608107", "mag": 2.1, "time": 1507134616795, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9268, 38.3958, 7.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904171", "mag": 1.38, "time": 1507133031670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.614333, 36.881, 6.94 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904166", "mag": 2.71, "time": 1507132718170, "felt": 28, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.609333, 36.8815, 6.65 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989087", "mag": 1.4, "time": 1507131238883, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.032, 63.5134, 6.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0yw", "mag": 4.4, "time": 1507130270240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7831, 15.8774, 9.59 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989083", "mag": 2.0, "time": 1507129786603, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.5468, 62.9914, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989080", "mag": 1.7, "time": 1507129070012, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8528, 63.1143, 130.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b14r", "mag": 2.9, "time": 1507127377130, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -78.3466, -0.2479, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608088", "mag": 1.1, "time": 1507126739396, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.8623, 39.6344, 5.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0xy", "mag": 4.3, "time": 1507120048520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.219, 14.9246, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018272", "mag": 1.04, "time": 1507119983420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.979333, 33.952, 16.95 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018264", "mag": 1.21, "time": 1507118298180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.153667, 33.576, 12.56 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988954", "mag": 1.4, "time": 1507117165370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.0651, 59.0371, 113.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988951", "mag": 1.7, "time": 1507117164179, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7431, 61.7579, 50.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988955", "mag": 1.2, "time": 1507117137925, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.2404, 63.315, 3.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018256", "mag": 1.97, "time": 1507116401470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.047667, 33.9995, 14.99 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988947", "mag": 1.3, "time": 1507116091533, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.038, 61.8748, 115.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988943", "mag": 2.6, "time": 1507115904863, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -138.3287, 60.8439, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259149", "mag": 1.42, "time": 1507115359390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.520833, 46.866833, 12.33 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988941", "mag": 2.0, "time": 1507115138670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7265, 59.549, 35.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988937", "mag": 1.7, "time": 1507114508883, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.561, 63.6903, 125.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904051", "mag": 1.09, "time": 1507113834280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.793, 38.8355, 1.85 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018224", "mag": 1.17, "time": 1507113370200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.608833, 33.080833, 11.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904041", "mag": 1.12, "time": 1507113327750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.942, 36.506, 4.31 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251097", "mag": 2.09, "time": 1507111719760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.414333, 42.55, 7.34 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904031", "mag": 0.97, "time": 1507110773350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.365667, 36.7845, 3.47 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259134", "mag": 2.46, "time": 1507108546600, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.527833, 46.867833, 13.28 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018200", "mag": 1.17, "time": 1507108523230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.5975, 34.0275, 11.16 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904011", "mag": 1.65, "time": 1507108226290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.59, 39.034, 1.81 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988931", "mag": 1.6, "time": 1507107916290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.4053, 65.8348, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018192", "mag": 1.04, "time": 1507107119810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.243833, 34.561167, 7.55 ] } }, +{ "type": "Feature", "properties": { "id": "uw61337191", "mag": 1.11, "time": 1507106498380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.3995, 47.466167, 20.06 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988930", "mag": 1.5, "time": 1507105167087, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3314, 63.0932, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903991", "mag": 1.0, "time": 1507105008930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.831667, 37.479167, 7.18 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0vg", "mag": 4.8, "time": 1507102453200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0265, 15.081, 39.52 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251092", "mag": 1.15, "time": 1507102301120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -113.109167, 37.453, 7.33 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903961", "mag": 0.99, "time": 1507102290690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.886, 37.634, 6.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903951", "mag": 1.13, "time": 1507102067530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.873, 37.655, 2.24 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988890", "mag": 2.1, "time": 1507101218109, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.6853, 59.7843, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903941", "mag": 1.93, "time": 1507099899370, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.174833, 36.7355, 8.83 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988888", "mag": 2.1, "time": 1507099796449, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.599, 58.1927, 18.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988886", "mag": 1.1, "time": 1507099794659, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.1044, 65.1213, 20.9 ] } }, +{ "type": "Feature", "properties": { "id": "hv61932126", "mag": 2.54, "time": 1507098254160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.471, 19.958167, 34.056 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018128", "mag": 1.48, "time": 1507095935630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.237333, 33.3585, 9.93 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988874", "mag": 2.0, "time": 1507095643589, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.4213, 59.0929, 75.6 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259124", "mag": 1.12, "time": 1507094472670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5195, 46.889167, 10.71 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0ue", "mag": 4.7, "time": 1507093737820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 145.7448, 18.3756, 172.11 ] } }, +{ "type": "Feature", "properties": { "id": "hv61932021", "mag": 1.47, "time": 1507093555340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.7645, 19.608333, 19.406 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251087", "mag": 1.84, "time": 1507092267430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.456667, 42.600833, 1.84 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988835", "mag": 1.4, "time": 1507091990426, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.8997, 62.5624, 2.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988834", "mag": 2.0, "time": 1507091511196, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.6239, 61.9391, 35.9 ] } }, +{ "type": "Feature", "properties": { "id": "hv61931981", "mag": 2.06, "time": 1507091217900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.6845, 18.778833, 34.132 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988831", "mag": 1.7, "time": 1507090320674, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.0205, 61.3011, 30.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988828", "mag": 1.6, "time": 1507090167802, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.1141, 63.8125, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018104", "mag": 0.97, "time": 1507089080620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.364, 33.395667, 5.23 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018096", "mag": 1.15, "time": 1507088756230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.118, 33.743333, 14.37 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0th", "mag": 5.0, "time": 1507087351060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.1517, -31.5827, 35.55 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903886", "mag": 1.89, "time": 1507087145860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.157333, 36.593167, 6.68 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903881", "mag": 1.09, "time": 1507086787130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.718666, 38.771667, 2.16 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0t5", "mag": 5.2, "time": 1507086128100, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -68.1988, -23.1056, 126.96 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608095", "mag": 1.8, "time": 1507085141975, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.2313, 37.1571, 11.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988758", "mag": 1.7, "time": 1507084302637, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.3056, 61.634, 42.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903856", "mag": 1.42, "time": 1507084182620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.847167, 37.6515, 3.01 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988756", "mag": 1.9, "time": 1507083972695, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.8168, 61.2547, 28.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018048", "mag": 1.01, "time": 1507081338310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.112167, 34.101167, 8.93 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259119", "mag": 1.6, "time": 1507080820140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.521833, 46.872833, 10.74 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259154", "mag": 1.65, "time": 1507080779330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5265, 46.876167, 11.17 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988720", "mag": 2.3, "time": 1507079042841, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.4064, 60.3952, 12.4 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608069", "mag": 1.7, "time": 1507077765338, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.5495, 40.2609, 8.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988717", "mag": 1.6, "time": 1507077365759, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3311, 63.2608, 0.8 ] } }, +{ "type": "Feature", "properties": { "id": "hv61931706", "mag": 1.47, "time": 1507077049100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.6385, 19.553667, 11.424 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018040", "mag": 0.98, "time": 1507076389190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.269, 34.0685, 15.7 ] } }, +{ "type": "Feature", "properties": { "id": "uw61337006", "mag": 0.96, "time": 1507074699210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.751333, 47.996333, 14.52 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0rt", "mag": 4.2, "time": 1507074238890, "felt": 7, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -82.7745, 8.5663, 30.59 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018024", "mag": 1.57, "time": 1507073295750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.681, 35.0345, -0.82 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988594", "mag": 2.0, "time": 1507073162743, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2617, 62.1345, 75.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988588", "mag": 1.3, "time": 1507072732101, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.2839, 61.0371, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "uw61336986", "mag": 1.86, "time": 1507072508440, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.616667, 48.275333, 6.9 ] } }, +{ "type": "Feature", "properties": { "id": "uw61336981", "mag": 1.89, "time": 1507072212820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.6095, 48.259, 5.47 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988584", "mag": 1.0, "time": 1507071678363, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3354, 64.9934, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903836", "mag": 1.12, "time": 1507071527650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.805, 38.822667, 2.85 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903831", "mag": 1.06, "time": 1507071133930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.808998, 38.823166, 1.74 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994062", "mag": 1.2, "time": 1507071050929, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8464, 63.0394, 121.6 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608062", "mag": 1.5, "time": 1507069440991, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.445, 37.5469, 5.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903806", "mag": 1.23, "time": 1507069427950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.739333, 38.805667, 1.44 ] } }, +{ "type": "Feature", "properties": { "id": "uw61336956", "mag": 1.0, "time": 1507069356480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.319167, 46.078167, -1.11 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988555", "mag": 2.0, "time": 1507069258013, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.1558, 67.7665, 10.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988552", "mag": 1.6, "time": 1507069137803, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.3107, 61.1448, 20.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0q2", "mag": 4.2, "time": 1507068153470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2992, 15.6198, 60.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci38018000", "mag": 1.69, "time": 1507067212670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.446333, 34.153333, 6.34 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259099", "mag": 1.07, "time": 1507067005720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.4045, 43.682, 5.87 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988545", "mag": 1.7, "time": 1507066676846, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6733, 65.2302, 8.7 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608050", "mag": 1.7, "time": 1507066159273, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.0874, 39.024, 7.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017984", "mag": 1.71, "time": 1507065949300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.347667, 33.392, 3.2 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251062", "mag": 1.76, "time": 1507065772640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.412333, 42.583667, 5.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988519", "mag": 2.6, "time": 1507065657270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.2687, 57.0749, 82.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988491", "mag": 1.6, "time": 1507065428977, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -161.3929, 65.0131, 16.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988489", "mag": 1.2, "time": 1507065333200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.6212, 63.3407, 7.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988484", "mag": 2.3, "time": 1507065014972, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0452, 62.216, 67.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72905396", "mag": 1.11, "time": 1507064824530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.4595, 41.531833, 2.93 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251057", "mag": 2.05, "time": 1507064724100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.399, 42.521333, 8.16 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017976", "mag": 1.59, "time": 1507064335800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.445833, 34.1535, 6.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903776", "mag": 1.19, "time": 1507063701570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8805, 37.529167, 1.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0nr", "mag": 5.7, "time": 1507063144760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -49.3194, 13.4552, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903771", "mag": 2.49, "time": 1507062907080, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.767, 38.799167, 0.51 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988466", "mag": 1.3, "time": 1507062241011, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.5134, 62.1795, 23.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988439", "mag": 2.2, "time": 1507061510846, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.8761, 60.5934, 142.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0n8", "mag": 4.5, "time": 1507061510710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 166.7231, 55.3488, 28.06 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017952", "mag": 1.07, "time": 1507061299680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.4405, 34.156167, 8.27 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988437", "mag": 1.3, "time": 1507061230777, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.0856, 61.3457, 14.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988435", "mag": 1.5, "time": 1507060035702, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9837, 61.6046, 61.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903741", "mag": 1.18, "time": 1507059288800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.764831, 38.788502, -0.61 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017936", "mag": 1.69, "time": 1507059189120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.7955, 33.4895, 4.06 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994048", "mag": 1.6, "time": 1507059099655, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.6496, 59.6816, 88.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994047", "mag": 1.4, "time": 1507058879703, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.6613, 58.3127, 61.4 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608048", "mag": 1.1, "time": 1507058710135, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.9271, 40.1731, 13.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017912", "mag": 1.43, "time": 1507058424320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.440833, 34.1545, 6.88 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017904", "mag": 1.19, "time": 1507057846620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.1795, 35.002, -0.83 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017896", "mag": 1.26, "time": 1507057788590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.941667, 32.908, -0.33 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0lw", "mag": 5.2, "time": 1507057466210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -28.8364, -55.2702, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259069", "mag": 1.71, "time": 1507056294930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.503, 46.830333, 12.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988418", "mag": 1.8, "time": 1507056127213, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.6502, 57.4998, 47.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903726", "mag": 1.14, "time": 1507056074240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.84, 37.503833, 0.26 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988415", "mag": 1.4, "time": 1507055512017, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.8175, 61.6607, 28.4 ] } }, +{ "type": "Feature", "properties": { "id": "hv61931361", "mag": 2.65, "time": 1507055057800, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.324, 19.406667, 7.018 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017848", "mag": 1.04, "time": 1507054498390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.44, 34.157667, 8.94 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251037", "mag": 1.12, "time": 1507053937840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.424333, 42.592167, 6.15 ] } }, +{ "type": "Feature", "properties": { "id": "hv61931346", "mag": 2.16, "time": 1507053691890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.373667, 20.034833, 13.532 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259064", "mag": 1.12, "time": 1507053599620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.609167, 46.334833, -2.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988394", "mag": 1.6, "time": 1507052715999, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9718, 60.8946, 14.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988390", "mag": 1.9, "time": 1507052122028, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.3579, 61.0247, 111.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903716", "mag": 2.07, "time": 1507052014050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.787667, 37.598833, 5.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994042", "mag": 2.0, "time": 1507051700735, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.4244, 59.8428, 129.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0jm", "mag": 4.6, "time": 1507050191000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 140.1126, -2.5625, 21.57 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017808", "mag": 1.9, "time": 1507049580810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.445167, 33.264333, 2.22 ] } }, +{ "type": "Feature", "properties": { "id": "nn00608002", "mag": 1.2, "time": 1507049448566, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.2901, 37.8049, 7.5 ] } }, +{ "type": "Feature", "properties": { "id": "uu60251027", "mag": 1.41, "time": 1507048713320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.760333, 39.998667, 8.73 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988364", "mag": 1.1, "time": 1507048704427, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.9116, 61.1262, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988361", "mag": 1.8, "time": 1507048669896, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.1084, 64.9183, 18.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017800", "mag": 0.98, "time": 1507048261760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.446833, 34.154333, 7.94 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903676", "mag": 1.69, "time": 1507047264490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8285, 37.455833, 2.67 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903671", "mag": 1.3, "time": 1507047173830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.5795, 37.287833, 7.31 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017744", "mag": 1.05, "time": 1507046707770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.136833, 34.054167, 9.74 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903666", "mag": 2.58, "time": 1507046582120, "felt": 6, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.464333, 36.750833, 7.57 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988359", "mag": 1.4, "time": 1507045972022, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1249, 62.9454, 112.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988358", "mag": 1.6, "time": 1507045690910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.2536, 60.0003, 13.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994035", "mag": 1.7, "time": 1507044159018, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.6674, 59.3569, 72.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988345", "mag": 2.7, "time": 1507043705635, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0117, 59.5043, 89.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903631", "mag": 1.33, "time": 1507043277890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.800667, 38.820167, 3.51 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994033", "mag": 1.6, "time": 1507043019584, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3814, 58.3192, 13.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988343", "mag": 2.7, "time": 1507042999732, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.3915, 51.6134, 9.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994031", "mag": 1.7, "time": 1507042763401, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.1107, 59.3023, 7.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994030", "mag": 1.3, "time": 1507042659104, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9147, 62.9235, 104.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994029", "mag": 1.6, "time": 1507042166290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0354, 59.6428, 85.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0gv", "mag": 2.1, "time": 1507041358070, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.8228, 36.4458, 4.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988332", "mag": 1.4, "time": 1507041247450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2842, 62.1118, 75.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017688", "mag": 1.7, "time": 1507041034810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.665167, 35.975833, 2.12 ] } }, +{ "type": "Feature", "properties": { "id": "hv61931251", "mag": 2.87, "time": 1507040757870, "felt": 6, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.370833, 20.027333, 12.259 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0gr", "mag": 4.6, "time": 1507040383740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 175.9616, -39.6706, 78.62 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903611", "mag": 1.04, "time": 1507039230370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.979333, 37.537333, 3.49 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988330", "mag": 1.8, "time": 1507038947118, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.8047, 53.5035, 24.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0k7", "mag": 2.6, "time": 1507038712390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.1971, 51.3674, 18.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0gm", "mag": 4.5, "time": 1507038514350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 94.7848, 25.0488, 74.86 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988328", "mag": 1.3, "time": 1507038483396, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5284, 62.2253, 16.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994023", "mag": 1.9, "time": 1507038160436, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -162.9795, 54.3692, 39.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994021", "mag": 1.3, "time": 1507037424410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3659, 61.871, 45.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017640", "mag": 0.99, "time": 1507035054330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.962167, 34.044333, 11.19 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994019", "mag": 2.4, "time": 1507034930692, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -179.8074, 51.67, 77.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988323", "mag": 2.5, "time": 1507033401817, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -162.3851, 54.2478, 11.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988320", "mag": 1.8, "time": 1507033125169, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8594, 61.9955, 7.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903576", "mag": 1.25, "time": 1507033081250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.496833, 35.946833, 9.32 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988318", "mag": 1.5, "time": 1507032487878, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.705, 62.0401, 40.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903571", "mag": 1.19, "time": 1507032219730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.973167, 37.635667, 4.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988315", "mag": 1.6, "time": 1507031200996, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.1077, 57.8662, 5.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903561", "mag": 1.07, "time": 1507031172540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.802002, 38.825832, 2.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988314", "mag": 1.7, "time": 1507031152426, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.0389, 60.0214, 78.4 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259049", "mag": 2.51, "time": 1507030950500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.353833, 43.520167, 3.75 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903556", "mag": 1.59, "time": 1507030601280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.887667, 37.630333, 6.72 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017616", "mag": 1.23, "time": 1507030424420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.812833, 34.096833, 13.63 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017608", "mag": 1.47, "time": 1507030255050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.808167, 34.092333, 14.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903546", "mag": 1.09, "time": 1507029639750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.82267, 38.807835, 1.84 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988306", "mag": 2.7, "time": 1507027595732, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4068, 51.6479, 12.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903531", "mag": 1.14, "time": 1507027098870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.763168, 38.789001, 0.79 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988304", "mag": 1.4, "time": 1507026885090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.5708, 61.3679, 26.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994008", "mag": 1.6, "time": 1507025162686, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.958, 61.2532, 105.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16994007", "mag": 1.2, "time": 1507024176706, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1195, 62.8909, 99.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988295", "mag": 2.1, "time": 1507023250156, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.3958, 51.6323, 10.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988294", "mag": 1.3, "time": 1507023225669, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7855, 61.7554, 59.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988292", "mag": 2.6, "time": 1507022763592, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.7772, 53.1343, 25.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988287", "mag": 1.2, "time": 1507022053291, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.872, 64.5325, 18.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988284", "mag": 1.3, "time": 1507021950836, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.929, 64.5216, 18.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988282", "mag": 1.4, "time": 1507021938525, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.8923, 58.4847, 8.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017544", "mag": 1.28, "time": 1507021318130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.791333, 33.687167, 16.23 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988279", "mag": 2.0, "time": 1507020554043, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2158, 61.698, 77.3 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259034", "mag": 1.18, "time": 1507020432130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.521333, 46.873, 11.92 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0fa", "mag": 4.2, "time": 1507019233190, "felt": 43, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -72.0212, -33.014, 17.65 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988271", "mag": 1.8, "time": 1507019136375, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.1655, 60.4739, 86.3 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250997", "mag": 1.69, "time": 1507019083210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.137833, 42.522333, -0.39 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993998", "mag": 1.8, "time": 1507018712322, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.0756, 60.1685, 13.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903491", "mag": 1.22, "time": 1507017869360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.486, 36.378, 5.97 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017536", "mag": 1.46, "time": 1507016252180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.479, 32.737333, 7.83 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988268", "mag": 1.4, "time": 1507015945802, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.0368, 61.1636, 0.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988267", "mag": 1.2, "time": 1507015806607, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4998, 63.1031, 5.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017504", "mag": 1.41, "time": 1507014429310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.363333, 34.832, 3.07 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988254", "mag": 4.1, "time": 1507013968245, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -161.3923, 54.6037, 20.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988252", "mag": 1.7, "time": 1507013732258, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.7964, 59.8936, 15.8 ] } }, +{ "type": "Feature", "properties": { "id": "mb80259004", "mag": 1.07, "time": 1507013501160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.523, 46.877333, 10.49 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607998", "mag": 1.1, "time": 1507013301155, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.3199, 37.7813, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993990", "mag": 1.4, "time": 1507012650027, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.264, 62.5244, 86.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988247", "mag": 2.1, "time": 1507012115547, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4061, 51.6742, 14.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988245", "mag": 1.0, "time": 1507011961646, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.539, 63.1068, 11.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017496", "mag": 1.24, "time": 1507011934810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.013833, 33.662167, 11.95 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017488", "mag": 1.25, "time": 1507011688900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.047333, 33.171, 5.29 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993987", "mag": 1.9, "time": 1507011535768, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -175.4878, 51.73, 4.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993986", "mag": 2.3, "time": 1507011386112, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.3903, 51.6732, 5.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017472", "mag": 1.5, "time": 1507010945840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.936833, 33.147, 7.23 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988244", "mag": 1.2, "time": 1507010895307, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.6337, 63.3262, 13.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017464", "mag": 1.4, "time": 1507008876900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.4845, 32.748667, 13.78 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017456", "mag": 1.19, "time": 1507008741980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.783833, 33.267833, 11.48 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0ef", "mag": 4.9, "time": 1507008633680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.9398, 15.4089, 62.32 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258984", "mag": 1.01, "time": 1507006889790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.430667, 43.6785, 7.63 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258979", "mag": 1.31, "time": 1507006468040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5225, 46.871167, 10.98 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988238", "mag": 2.4, "time": 1507005858917, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.1659, 51.8129, 90.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993983", "mag": 1.4, "time": 1507004701069, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7077, 62.778, 79.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017432", "mag": 1.1, "time": 1507003677250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.790667, 33.485333, 4.63 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988237", "mag": 1.5, "time": 1507003090709, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.0237, 61.1529, 7.4 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258949", "mag": 1.2, "time": 1507002724530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.529833, 46.869, 10.38 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988235", "mag": 2.7, "time": 1507001740915, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -167.6571, 52.9982, 32.2 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607958", "mag": 1.2, "time": 1507001239948, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.3057, 38.4484, 5.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988229", "mag": 1.6, "time": 1506999699601, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.3039, 62.7285, 79.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988225", "mag": 1.7, "time": 1506999179710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.178, 66.888, 7.7 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258939", "mag": 1.1, "time": 1506998768510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.528833, 46.860333, 12.25 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988222", "mag": 2.7, "time": 1506998450736, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.4948, 53.5386, 57.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988221", "mag": 1.2, "time": 1506998296606, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3526, 63.268, 2.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988218", "mag": 1.0, "time": 1506997994823, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.5335, 53.8446, 6.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988217", "mag": 2.2, "time": 1506997972933, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.6125, 58.9289, 125.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903391", "mag": 1.03, "time": 1506997840780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.847336, 38.829834, 1.06 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903396", "mag": 1.23, "time": 1506997715100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.315667, 37.487833, 3.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017400", "mag": 1.05, "time": 1506997467730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.334333, 33.346333, 9.65 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993974", "mag": 1.4, "time": 1506996608838, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2536, 62.5803, 93.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988215", "mag": 1.6, "time": 1506996320652, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.155, 61.9755, 70.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993972", "mag": 1.6, "time": 1506995513010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.7768, 60.1335, 76.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993971", "mag": 1.2, "time": 1506995387104, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.6738, 61.6682, 50.5 ] } }, +{ "type": "Feature", "properties": { "id": "hv61930601", "mag": 2.1, "time": 1506994522010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.565506, 19.795834, 15.58 ] } }, +{ "type": "Feature", "properties": { "id": "ak16993970", "mag": 1.1, "time": 1506994269143, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.0156, 64.7374, 10.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903381", "mag": 1.16, "time": 1506991878630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.803169, 38.824001, 2.33 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017368", "mag": 1.36, "time": 1506989712460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.168667, 34.0055, 13.99 ] } }, +{ "type": "Feature", "properties": { "id": "uw61336686", "mag": 1.47, "time": 1506988725560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.044167, 49.145, -1.01 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988200", "mag": 2.8, "time": 1506988653897, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6324, 61.3885, 39.1 ] } }, +{ "type": "Feature", "properties": { "id": "nm60207781", "mag": 1.99, "time": 1506988371180, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -89.444833, 36.088167, 13.18 ] } }, +{ "type": "Feature", "properties": { "id": "us2000az70", "mag": 4.7, "time": 1506987102640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 91.8995, 12.8626, 27.25 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017360", "mag": 1.72, "time": 1506986970860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.674, 35.035333, -0.82 ] } }, +{ "type": "Feature", "properties": { "id": "us2000azc7", "mag": 2.4, "time": 1506986577400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.6124, 36.8167, 5.123 ] } }, +{ "type": "Feature", "properties": { "id": "nm60207771", "mag": 1.11, "time": 1506984309110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -89.517167, 36.232667, 8.34 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017336", "mag": 1.0, "time": 1506984123180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.2705, 33.975833, 4.84 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903356", "mag": 1.77, "time": 1506983102870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.991833, 40.153833, 4.17 ] } }, +{ "type": "Feature", "properties": { "id": "uw61336646", "mag": 1.36, "time": 1506982150130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.4015, 46.173833, -0.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ayh7", "mag": 4.4, "time": 1506982074330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -68.7039, -22.2431, 108.4 ] } }, +{ "type": "Feature", "properties": { "id": "uw61336631", "mag": 1.27, "time": 1506980575160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.930333, 48.1035, -1.28 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aya0", "mag": 5.3, "time": 1506980277150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 167.7345, -19.4817, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903316", "mag": 1.65, "time": 1506979898940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.802, 38.824833, 2.33 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903311", "mag": 1.09, "time": 1506979301540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.531667, 37.139833, 8.93 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903306", "mag": 1.08, "time": 1506978484410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.444667, 36.959667, 6.72 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903301", "mag": 1.46, "time": 1506978005870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.351667, 39.5165, 4.32 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258889", "mag": 2.36, "time": 1506975888040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -113.9055, 47.358667, 13.73 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903286", "mag": 0.97, "time": 1506975385450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.946833, 37.590333, 0.28 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017200", "mag": 0.96, "time": 1506974805670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.503167, 33.8695, -0.36 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axzc", "mag": 2.8, "time": 1506974101570, "felt": 18, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -102.3612, 35.5909, 5.45 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903271", "mag": 2.25, "time": 1506973045100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.609167, 36.880667, 6.31 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258884", "mag": 1.4, "time": 1506972979050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5355, 46.8805, 12.28 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903261", "mag": 1.85, "time": 1506971674240, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.831833, 37.455667, 1.78 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017136", "mag": 1.08, "time": 1506971129830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.192, 34.993167, -0.84 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258874", "mag": 1.49, "time": 1506970982010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.4715, 45.995667, -2.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017120", "mag": 0.99, "time": 1506970881590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.649167, 35.932833, 2.94 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903251", "mag": 1.78, "time": 1506970847010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.308833, 40.750667, -0.79 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903246", "mag": 1.41, "time": 1506970631190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.932667, 35.639, 4.96 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903241", "mag": 1.21, "time": 1506970286520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.679167, 38.533833, 5.88 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017104", "mag": 1.66, "time": 1506970188840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.133167, 34.279, 6.09 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axxi", "mag": 4.6, "time": 1506969995010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 102.3915, -7.056, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258869", "mag": 1.46, "time": 1506969854670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.523167, 46.87, 10.71 ] } }, +{ "type": "Feature", "properties": { "id": "ci38017064", "mag": 1.26, "time": 1506968962060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.623333, 33.912167, 10.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903226", "mag": 0.96, "time": 1506968036980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.880333, 37.530667, 2.11 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axwl", "mag": 4.6, "time": 1506968031500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 94.5291, 21.4218, 96.74 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904986", "mag": 1.14, "time": 1506968001000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.718167, 40.935167, 12.07 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988088", "mag": 2.2, "time": 1506967247502, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.9366, 59.642, 98.9 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607868", "mag": 1.0, "time": 1506966403731, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.4944, 37.2386, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903211", "mag": 0.98, "time": 1506965951300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.833, 37.457667, 1.76 ] } }, +{ "type": "Feature", "properties": { "id": "ci37167228", "mag": 1.57, "time": 1506964185870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.4615, 34.328667, 3.74 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016984", "mag": 1.25, "time": 1506964183390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.466833, 34.3255, 4.39 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903196", "mag": 1.36, "time": 1506963756010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.827833, 37.456667, 2.57 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258854", "mag": 1.03, "time": 1506962682500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.528667, 46.8625, 13.48 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903176", "mag": 1.21, "time": 1506962394170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.827833, 37.457167, 2.28 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903166", "mag": 1.88, "time": 1506961834060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.827167, 37.4555, 1.91 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903156", "mag": 1.69, "time": 1506961396620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8265, 37.456333, 2.16 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903146", "mag": 3.02, "time": 1506961086740, "felt": 5, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.829, 37.453667, 2.61 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016888", "mag": 1.17, "time": 1506960224640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.0325, 33.879333, -0.97 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903131", "mag": 1.08, "time": 1506959715450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.371333, 35.706833, 1.86 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988071", "mag": 1.4, "time": 1506959208997, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -142.9837, 67.1697, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607854", "mag": 1.7, "time": 1506958960926, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -113.8425, 36.5559, 8.1 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250907", "mag": 2.05, "time": 1506957621760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4145, 42.546333, 7.87 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903111", "mag": 1.41, "time": 1506957279300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.997333, 36.462667, 5.69 ] } }, +{ "type": "Feature", "properties": { "id": "nm60207666", "mag": 2.19, "time": 1506957159610, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -89.8025, 36.5505, 12.47 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988065", "mag": 2.7, "time": 1506956391417, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.8151, 61.2492, 19.9 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258839", "mag": 1.19, "time": 1506955175250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.526167, 46.870333, 10.04 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axtv", "mag": 4.7, "time": 1506953290020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 127.1289, 2.6798, 25.66 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903096", "mag": 1.04, "time": 1506952925800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.822667, 37.513833, 8.22 ] } }, +{ "type": "Feature", "properties": { "id": "ak16987055", "mag": 1.1, "time": 1506952513029, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.2609, 64.6409, 14.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903081", "mag": 1.18, "time": 1506950851670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.751663, 38.832832, 0.68 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axtl", "mag": 4.7, "time": 1506950716850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 51.6372, 28.6895, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258829", "mag": 1.08, "time": 1506950613020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.524667, 46.868167, 9.75 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258824", "mag": 1.16, "time": 1506950147300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.523333, 46.866667, 11.08 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250902", "mag": 1.34, "time": 1506949268120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.084, 44.7795, 11.23 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258814", "mag": 1.19, "time": 1506949148400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.527333, 46.855833, 14.0 ] } }, +{ "type": "Feature", "properties": { "id": "hv61929981", "mag": 2.4, "time": 1506948942340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.592667, 19.465333, 0.033 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axsh", "mag": 2.6, "time": 1506947996150, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.5037, 36.2851, 3.93 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258799", "mag": 1.69, "time": 1506947507620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.527833, 46.869833, 10.17 ] } }, +{ "type": "Feature", "properties": { "id": "ak16987046", "mag": 1.5, "time": 1506947130357, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1189, 63.1205, 16.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903071", "mag": 1.5, "time": 1506946592080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.885667, 36.3165, 6.48 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axs4", "mag": 4.3, "time": 1506946114440, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -61.2682, 13.209, 136.91 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axsa", "mag": 4.3, "time": 1506945001990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 176.4854, -37.3176, 354.86 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258789", "mag": 2.2, "time": 1506944699010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.533, 46.869833, 13.3 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250897", "mag": 1.6, "time": 1506943796070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.218667, 42.571667, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16986042", "mag": 1.3, "time": 1506943225411, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.912, 63.0196, 66.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16986039", "mag": 1.4, "time": 1506941366267, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.3257, 63.3321, 6.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016776", "mag": 1.44, "time": 1506940900650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.510667, 34.2985, 9.93 ] } }, +{ "type": "Feature", "properties": { "id": "hv61929926", "mag": 2.13, "time": 1506940825170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.524002, 19.919001, 20.11 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258769", "mag": 1.48, "time": 1506940203900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.33, 46.119833, 6.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axrm", "mag": 4.9, "time": 1506939736050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -88.2184, 12.3486, 35.55 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016768", "mag": 1.12, "time": 1506938746370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.067167, 34.208333, 2.04 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016760", "mag": 1.75, "time": 1506938502900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.064833, 34.207833, 2.06 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903041", "mag": 1.87, "time": 1506938425810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.908833, 36.368667, 8.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16985035", "mag": 1.7, "time": 1506938303105, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.1495, 63.1057, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016752", "mag": 1.08, "time": 1506938024070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.448833, 33.481, 8.33 ] } }, +{ "type": "Feature", "properties": { "id": "ak16985032", "mag": 1.1, "time": 1506937259442, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.8806, 64.6842, 6.7 ] } }, +{ "type": "Feature", "properties": { "id": "nm60207636", "mag": 1.71, "time": 1506936707930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -90.1365, 35.88, 10.55 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250892", "mag": 1.5, "time": 1506936161680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.480833, 42.384833, 5.67 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258764", "mag": 2.37, "time": 1506936112630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.534333, 46.8675, 13.36 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258759", "mag": 3.08, "time": 1506934838560, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.529167, 46.872333, 11.44 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016728", "mag": 1.01, "time": 1506934828760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.065667, 34.2065, 1.91 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axr0", "mag": 4.3, "time": 1506933668380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.8824, 16.708, 65.53 ] } }, +{ "type": "Feature", "properties": { "id": "ci37398445", "mag": 0.97, "time": 1506933339570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.460667, 34.332333, 5.88 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903031", "mag": 1.45, "time": 1506933218670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.812667, 38.805, 2.29 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0e8", "mag": 1.4, "time": 1506931958320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -71.32, 43.6653, 7.15 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250882", "mag": 1.44, "time": 1506931830720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4165, 42.520333, 8.15 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250877", "mag": 1.13, "time": 1506930804620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.414333, 42.544333, 7.62 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016688", "mag": 1.28, "time": 1506929655950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.003333, 33.1775, 4.99 ] } }, +{ "type": "Feature", "properties": { "id": "ak16985021", "mag": 2.3, "time": 1506927665686, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.5448, 63.1998, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16985020", "mag": 1.7, "time": 1506927499500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.4204, 67.3068, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258749", "mag": 1.94, "time": 1506926930660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.523333, 46.874, 11.51 ] } }, +{ "type": "Feature", "properties": { "id": "ak16985018", "mag": 1.1, "time": 1506926698712, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.829, 65.5759, 9.2 ] } }, +{ "type": "Feature", "properties": { "id": "hv61929841", "mag": 1.98, "time": 1506926298850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.412338, 19.245501, 33.84 ] } }, +{ "type": "Feature", "properties": { "id": "se60045313", "mag": 1.9, "time": 1506925923790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -82.894667, 34.9895, 0.16 ] } }, +{ "type": "Feature", "properties": { "id": "ak16984019", "mag": 1.1, "time": 1506925731082, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.5467, 65.155, 3.8 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258744", "mag": 1.32, "time": 1506925562230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.528833, 46.867167, 11.58 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016672", "mag": 0.97, "time": 1506925004450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.422833, 33.04, 10.21 ] } }, +{ "type": "Feature", "properties": { "id": "ak16984018", "mag": 1.4, "time": 1506924871383, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.2817, 61.9608, 23.3 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250872", "mag": 1.58, "time": 1506924776930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.033833, 38.600333, 7.01 ] } }, +{ "type": "Feature", "properties": { "id": "ak16984009", "mag": 3.0, "time": 1506924381290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.1032, 58.7701, 99.0 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250867", "mag": 1.58, "time": 1506924167170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.409667, 42.562167, 7.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axq4", "mag": 4.2, "time": 1506924037060, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 174.3565, -41.7636, 24.13 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016664", "mag": 1.49, "time": 1506923205850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.589167, 32.780833, 12.71 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016656", "mag": 2.39, "time": 1506923145240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.009833, 33.179833, 9.12 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axq3", "mag": 4.7, "time": 1506923126070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -179.4587, -21.8514, 582.95 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016648", "mag": 2.46, "time": 1506922959220, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.010167, 33.179, 8.89 ] } }, +{ "type": "Feature", "properties": { "id": "uw61336471", "mag": 3.25, "time": 1506922219710, "felt": 66, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.8935, 47.887833, 54.22 ] } }, +{ "type": "Feature", "properties": { "id": "nm60207631", "mag": 1.51, "time": 1506922179830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -89.527833, 36.243667, 7.74 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607885", "mag": 1.0, "time": 1506921346217, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.0518, 37.0814, 8.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axpv", "mag": 4.8, "time": 1506921205270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 72.4324, 38.1132, 115.18 ] } }, +{ "type": "Feature", "properties": { "id": "ak16983007", "mag": 1.4, "time": 1506919945331, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.5212, 66.5767, 2.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902986", "mag": 1.91, "time": 1506919685230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.524833, 35.967333, 10.71 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axpm", "mag": 2.2, "time": 1506919604410, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.5118, 36.9048, 4.52 ] } }, +{ "type": "Feature", "properties": { "id": "uw61336446", "mag": 1.27, "time": 1506919122930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.245667, 46.345833, 7.97 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016584", "mag": 2.31, "time": 1506918555650, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.7985, 33.500167, 5.3 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250862", "mag": 1.41, "time": 1506917347110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.411167, 42.640167, -1.04 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016576", "mag": 1.0, "time": 1506916919110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.43, 33.028833, 3.21 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016568", "mag": 1.08, "time": 1506916645840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.048333, 33.2415, 5.47 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250857", "mag": 1.42, "time": 1506916237980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.446167, 42.608333, 6.68 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016552", "mag": 1.32, "time": 1506915577280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.482167, 35.754, 3.27 ] } }, +{ "type": "Feature", "properties": { "id": "hv61929701", "mag": 2.26, "time": 1506915466040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.021835, 19.397499, 0.02 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axp9", "mag": 2.5, "time": 1506915178660, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.5196, 36.2819, 4.38 ] } }, +{ "type": "Feature", "properties": { "id": "ak16982006", "mag": 3.4, "time": 1506913363596, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.9176, 55.7636, 20.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axp5", "mag": 2.7, "time": 1506913350820, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5073, 46.8582, 10.64 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258724", "mag": 1.27, "time": 1506912496350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -113.017333, 44.484667, 7.23 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902956", "mag": 1.67, "time": 1506912463450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.4705, 40.704167, 17.1 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250847", "mag": 1.01, "time": 1506911908120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.418333, 42.516667, 6.74 ] } }, +{ "type": "Feature", "properties": { "id": "ak16982001", "mag": 1.1, "time": 1506909373983, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.8167, 61.2439, 26.6 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250837", "mag": 1.18, "time": 1506909364560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.411833, 42.520667, 7.35 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258714", "mag": 1.56, "time": 1506908562340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.523167, 46.872833, 12.04 ] } }, +{ "type": "Feature", "properties": { "id": "ak16981996", "mag": 1.3, "time": 1506908205944, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.5285, 63.1691, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16982000", "mag": 1.4, "time": 1506908156528, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.6012, 59.5948, 56.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axnx", "mag": 2.6, "time": 1506907742490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4159, 42.5178, 6.97 ] } }, +{ "type": "Feature", "properties": { "id": "ak16981992", "mag": 1.8, "time": 1506907678571, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.2312, 63.3329, 7.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902936", "mag": 1.52, "time": 1506905787330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.426, 38.404, 7.4 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250827", "mag": 1.35, "time": 1506905780190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4175, 42.518833, 6.5 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250822", "mag": 1.43, "time": 1506905571670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.422333, 42.512667, 7.8 ] } }, +{ "type": "Feature", "properties": { "id": "hv61929496", "mag": 1.71, "time": 1506905364520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.584503, 19.484333, 2.03 ] } }, +{ "type": "Feature", "properties": { "id": "ak16981986", "mag": 1.5, "time": 1506903663272, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.7914, 61.5177, 34.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016496", "mag": 1.6, "time": 1506903468250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.793667, 33.502333, 5.16 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016488", "mag": 1.3, "time": 1506903227250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.5175, 34.2865, 7.02 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607841", "mag": 2.5, "time": 1506901760242, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.7954, 37.1971, 7.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902911", "mag": 2.66, "time": 1506901676700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -124.506167, 40.3085, 21.45 ] } }, +{ "type": "Feature", "properties": { "id": "ak16981979", "mag": 2.0, "time": 1506901404559, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6022, 63.105, 120.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990868", "mag": 2.0, "time": 1506900397361, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.1198, 58.9916, 108.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16980981", "mag": 1.3, "time": 1506899671796, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -138.1479, 60.8928, 4.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016456", "mag": 1.6, "time": 1506899253540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.2755, 33.976333, 5.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902901", "mag": 1.02, "time": 1506898875730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.810165, 38.816834, 1.1 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258679", "mag": 1.05, "time": 1506897817900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.525833, 46.891833, 12.84 ] } }, +{ "type": "Feature", "properties": { "id": "ak16980976", "mag": 1.1, "time": 1506897164997, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.9167, 60.5402, 8.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16980971", "mag": 1.8, "time": 1506896659586, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.1362, 61.9345, 11.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16980968", "mag": 2.0, "time": 1506896402168, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.9985, 65.5166, 15.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16980965", "mag": 1.5, "time": 1506895579977, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.6538, 59.9364, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016448", "mag": 1.52, "time": 1506895319020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.830833, 33.712, 16.9 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70236163", "mag": 2.36, "time": 1506894257160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.905833, 36.996333, 9.62 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990861", "mag": 1.1, "time": 1506893923115, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.3425, 61.0789, 57.8 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607826", "mag": 1.4, "time": 1506893733690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.6519, 39.1963, 5.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16980964", "mag": 1.2, "time": 1506892711109, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.8709, 61.4311, 46.5 ] } }, +{ "type": "Feature", "properties": { "id": "uw61336341", "mag": 1.82, "time": 1506892129610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.567667, 49.3235, -1.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990859", "mag": 1.9, "time": 1506891719402, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.8509, 57.8862, 54.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16980963", "mag": 1.2, "time": 1506891059795, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.5477, 60.1976, 34.8 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258669", "mag": 1.06, "time": 1506890613170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.515667, 46.8785, 11.55 ] } }, +{ "type": "Feature", "properties": { "id": "ak16980956", "mag": 2.1, "time": 1506890459542, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.2618, 53.748, 49.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16980945", "mag": 1.5, "time": 1506890359030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.5485, 59.782, 2.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16980939", "mag": 2.7, "time": 1506890337968, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.2691, 59.2151, 55.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16980943", "mag": 2.0, "time": 1506890332904, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.1083, 61.5648, 11.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axlg", "mag": 2.5, "time": 1506890067740, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -96.7952, 35.9855, 3.13 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902871", "mag": 1.2, "time": 1506890044550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.619333, 36.969667, 5.21 ] } }, +{ "type": "Feature", "properties": { "id": "ak16980936", "mag": 1.3, "time": 1506889965804, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.4052, 62.336, 46.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16980933", "mag": 1.6, "time": 1506888599699, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.5246, 51.8512, 19.4 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258664", "mag": 1.08, "time": 1506888514540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.525167, 46.889833, 12.19 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902866", "mag": 1.72, "time": 1506888000180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.3795, 40.710333, 18.86 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axkq", "mag": 3.3, "time": 1506887023210, "felt": 9, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.4467, 36.1992, 5.42 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axkh", "mag": 4.4, "time": 1506885748640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.3923, 15.6065, 68.63 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axkg", "mag": 4.7, "time": 1506885628670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 131.0709, 30.4016, 52.09 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902851", "mag": 1.6, "time": 1506885379850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.806167, 38.816833, 2.01 ] } }, +{ "type": "Feature", "properties": { "id": "ak16979941", "mag": 1.1, "time": 1506885213719, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2184, 62.3649, 80.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902846", "mag": 1.16, "time": 1506883965960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.676, 37.612, 3.61 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607803", "mag": 1.2, "time": 1506883429003, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.7983, 37.0626, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990850", "mag": 1.4, "time": 1506881346159, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.4695, 60.2829, 104.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902836", "mag": 1.01, "time": 1506881205680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.800835, 38.831833, 1.97 ] } }, +{ "type": "Feature", "properties": { "id": "ak16979936", "mag": 1.1, "time": 1506880968876, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.7414, 62.1039, 54.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607807", "mag": 1.1, "time": 1506880810251, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.1156, 38.2725, 9.6 ] } }, +{ "type": "Feature", "properties": { "id": "hv61928951", "mag": 2.13, "time": 1506880210700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.408493, 19.198166, 32.85 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607796", "mag": 1.4, "time": 1506880150990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.7769, 37.082, 5.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16979932", "mag": 1.3, "time": 1506879650012, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.5344, 59.9497, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16979928", "mag": 1.4, "time": 1506878561352, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.7881, 59.4532, 86.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axj4", "mag": 4.9, "time": 1506877281250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.6588, -24.2867, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "uw61336301", "mag": 1.08, "time": 1506877137600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.289333, 46.525667, 12.49 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axiu", "mag": 4.8, "time": 1506876485410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -76.1816, -45.7692, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902831", "mag": 2.39, "time": 1506876142050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8365, 37.5015, 0.38 ] } }, +{ "type": "Feature", "properties": { "id": "ak16978937", "mag": 1.2, "time": 1506875682364, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.0123, 63.225, 1.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990844", "mag": 1.0, "time": 1506875638383, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.3476, 60.399, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16978936", "mag": 1.3, "time": 1506875438694, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1025, 62.0191, 64.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990842", "mag": 1.6, "time": 1506873845866, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -173.7815, 51.9812, 27.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16977948", "mag": 2.0, "time": 1506871550948, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.142, 60.236, 132.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axi9", "mag": 4.2, "time": 1506870604300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.8183, -18.2769, 600.28 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902801", "mag": 1.08, "time": 1506869234490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.736333, 37.427833, 11.17 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902796", "mag": 0.97, "time": 1506869005720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.80983, 38.822666, 2.38 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902791", "mag": 1.02, "time": 1506868646100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.018, 37.4345, 4.76 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axi8", "mag": 4.5, "time": 1506868536330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 92.3426, 12.898, 30.37 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902781", "mag": 1.48, "time": 1506867941180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.033833, 37.4125, 0.87 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axhz", "mag": 4.5, "time": 1506867628470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 142.306, 40.1598, 57.26 ] } }, +{ "type": "Feature", "properties": { "id": "uw61336271", "mag": 1.68, "time": 1506867619960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.078833, 44.103667, -0.53 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990839", "mag": 1.7, "time": 1506867169462, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.3848, 56.4945, 79.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axhv", "mag": 5.0, "time": 1506866880330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.5287, -22.8028, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16976960", "mag": 1.2, "time": 1506866784677, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.7487, 60.0824, 8.2 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250707", "mag": 2.06, "time": 1506866738590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.447833, 42.650333, 2.93 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258644", "mag": 1.07, "time": 1506866437550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.525833, 46.866, 11.8 ] } }, +{ "type": "Feature", "properties": { "id": "hv61928751", "mag": 1.73, "time": 1506865813980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.633499, 19.408501, 4.16 ] } }, +{ "type": "Feature", "properties": { "id": "ak16976951", "mag": 1.0, "time": 1506864160172, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.909, 58.2689, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16976949", "mag": 1.0, "time": 1506864011046, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.6138, 60.5977, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990832", "mag": 1.4, "time": 1506863730810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.1725, 60.1804, 135.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16975974", "mag": 1.1, "time": 1506862307453, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.3672, 61.3015, 47.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axhf", "mag": 4.6, "time": 1506862144080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 91.9129, 12.7332, 25.97 ] } }, +{ "type": "Feature", "properties": { "id": "ak16975970", "mag": 1.3, "time": 1506861392092, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.0328, 59.3749, 6.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16975965", "mag": 1.4, "time": 1506860447567, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.3802, 59.7999, 122.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16975961", "mag": 1.9, "time": 1506860241377, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.3702, 58.1855, 1.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016296", "mag": 0.97, "time": 1506860065660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.200333, 33.034167, 6.74 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902736", "mag": 1.01, "time": 1506859858880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.793999, 38.812668, 3.13 ] } }, +{ "type": "Feature", "properties": { "id": "ak16975960", "mag": 2.0, "time": 1506859830456, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -175.5366, 51.4282, 50.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16974988", "mag": 1.1, "time": 1506859403703, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.7216, 57.888, 61.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607763", "mag": 2.0, "time": 1506858283945, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.6834, 40.0949, 13.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16974986", "mag": 1.5, "time": 1506857978595, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.6219, 59.7494, 10.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016272", "mag": 1.31, "time": 1506857701950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.46, 34.330833, 3.08 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258619", "mag": 1.22, "time": 1506857080460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.509667, 46.908167, 15.76 ] } }, +{ "type": "Feature", "properties": { "id": "ak16974980", "mag": 2.0, "time": 1506856935435, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4679, 51.6302, 13.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16974977", "mag": 1.7, "time": 1506856591674, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.0171, 58.9928, 112.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990818", "mag": 1.6, "time": 1506856352544, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.6069, 60.035, 157.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902701", "mag": 1.04, "time": 1506856284600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.718, 38.742333, 1.86 ] } }, +{ "type": "Feature", "properties": { "id": "ak16974975", "mag": 1.2, "time": 1506856083450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.5011, 64.299, 14.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16974972", "mag": 1.5, "time": 1506855936313, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.5182, 59.9216, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016224", "mag": 1.28, "time": 1506855241040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.731167, 33.649, 12.54 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990815", "mag": 2.8, "time": 1506854643419, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 179.4705, 51.8814, 165.3 ] } }, +{ "type": "Feature", "properties": { "id": "hv61928636", "mag": 2.82, "time": 1506854300970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.485667, 20.355333, 14.282 ] } }, +{ "type": "Feature", "properties": { "id": "ak16974969", "mag": 1.4, "time": 1506854297360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.6332, 59.9863, 7.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902676", "mag": 1.69, "time": 1506853476410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.984, 37.5295, 2.12 ] } }, +{ "type": "Feature", "properties": { "id": "ak16973994", "mag": 1.0, "time": 1506853292474, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.0636, 62.2825, 41.1 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607794", "mag": 1.1, "time": 1506852962371, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9213, 38.3646, 5.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016200", "mag": 1.06, "time": 1506852815200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.791833, 33.502167, 4.66 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axgb", "mag": 5.1, "time": 1506852415110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -176.6916, -24.4751, 87.71 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016192", "mag": 1.27, "time": 1506852211900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.464167, 36.311167, 0.93 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990809", "mag": 1.3, "time": 1506851397558, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.4428, 58.7981, 124.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16973987", "mag": 1.3, "time": 1506850332700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.1498, 59.6631, 104.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902646", "mag": 1.37, "time": 1506850223860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.452, 37.402167, 4.64 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axfz", "mag": 4.0, "time": 1506849733290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.8612, 14.9405, 53.39 ] } }, +{ "type": "Feature", "properties": { "id": "ak16973981", "mag": 1.6, "time": 1506849720561, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2003, 60.1713, 129.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16973012", "mag": 1.1, "time": 1506849332753, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.7558, 59.8604, 10.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axfu", "mag": 4.4, "time": 1506848263400, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.7814, 18.4858, 79.09 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016176", "mag": 1.75, "time": 1506848220800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.651333, 35.934333, 2.81 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016160", "mag": 1.37, "time": 1506846375610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.908333, 35.5955, 1.49 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990805", "mag": 2.5, "time": 1506845582617, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -169.7071, 51.7987, 13.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16972044", "mag": 1.1, "time": 1506843571095, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.4859, 61.0501, 21.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axfi", "mag": 4.1, "time": 1506843463030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -77.5019, -1.5006, 197.35 ] } }, +{ "type": "Feature", "properties": { "id": "ak16972038", "mag": 1.5, "time": 1506842124989, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.6539, 62.7976, 71.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16972036", "mag": 1.2, "time": 1506841940900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8258, 61.6968, 61.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258604", "mag": 1.59, "time": 1506841735050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.459167, 46.866, 10.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016112", "mag": 1.44, "time": 1506840801230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.2085, 34.452833, 11.88 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70236143", "mag": 1.72, "time": 1506840567300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.7785, 37.328333, 4.35 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990799", "mag": 1.1, "time": 1506840419377, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.7218, 59.2315, 9.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16971064", "mag": 2.6, "time": 1506838204059, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.5055, 59.3191, 8.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axek", "mag": 3.2, "time": 1506836917300, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.7711, 36.4532, 6.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16970116", "mag": 2.7, "time": 1506836847043, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.9474, 62.6019, 6.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902586", "mag": 1.42, "time": 1506836822020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8205, 37.604, 4.13 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902581", "mag": 1.71, "time": 1506836766960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8205, 37.604333, 4.0 ] } }, +{ "type": "Feature", "properties": { "id": "hv61928476", "mag": 1.81, "time": 1506836276760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.631836, 19.188999, 0.89 ] } }, +{ "type": "Feature", "properties": { "id": "ak16970114", "mag": 1.3, "time": 1506835946408, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.345, 60.1863, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250622", "mag": 2.13, "time": 1506835247610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.578, 38.7305, -0.01 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axe4", "mag": 4.2, "time": 1506834536440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 146.1269, -6.2836, 59.98 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axdz", "mag": 4.1, "time": 1506833874150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -85.5987, 9.126, 39.13 ] } }, +{ "type": "Feature", "properties": { "id": "ak16970083", "mag": 2.0, "time": 1506833288717, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.6914, 61.3678, 29.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16969148", "mag": 1.9, "time": 1506832174570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -175.9412, 51.6192, 50.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16969146", "mag": 1.0, "time": 1506831622152, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.577, 62.7735, 79.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016048", "mag": 1.04, "time": 1506831472900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.833167, 33.669167, 16.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci38016040", "mag": 1.1, "time": 1506831149410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.485, 36.3695, 1.6 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258549", "mag": 1.59, "time": 1506830710300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5235, 46.889833, 13.14 ] } }, +{ "type": "Feature", "properties": { "id": "hv61928346", "mag": 2.95, "time": 1506829826670, "felt": 21, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.095333, 19.715167, 33.794 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990790", "mag": 1.0, "time": 1506829471423, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.2898, 60.1429, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902546", "mag": 1.45, "time": 1506828244030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.157167, 36.626, 8.14 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258544", "mag": 1.11, "time": 1506828010380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.526333, 46.871, 10.92 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902531", "mag": 1.44, "time": 1506827498200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.228833, 36.619333, 4.82 ] } }, +{ "type": "Feature", "properties": { "id": "ak16968180", "mag": 2.0, "time": 1506827492404, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.739, 61.1833, 86.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axpk", "mag": 1.6, "time": 1506827393900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -70.9053, 41.6481, 6.51 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015992", "mag": 1.15, "time": 1506827015230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.3845, 35.111667, 5.93 ] } }, +{ "type": "Feature", "properties": { "id": "hv61928261", "mag": 2.05, "time": 1506825377030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.476502, 19.216, 37.47 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990784", "mag": 1.4, "time": 1506825243899, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.2232, 51.7576, 46.6 ] } }, +{ "type": "Feature", "properties": { "id": "uw61336131", "mag": 1.16, "time": 1506825168050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.9095, 48.316167, 1.09 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258539", "mag": 1.53, "time": 1506824807150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.528833, 46.877, 11.86 ] } }, +{ "type": "Feature", "properties": { "id": "ak16967237", "mag": 1.8, "time": 1506824784256, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.7866, 53.1332, 25.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990782", "mag": 2.0, "time": 1506823956350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -173.6834, 51.2465, 35.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990781", "mag": 1.3, "time": 1506823856677, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.521, 59.9658, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902506", "mag": 1.22, "time": 1506821920520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.7125, 37.351167, 7.83 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axct", "mag": 5.1, "time": 1506821726490, "felt": 125, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -73.1491, 7.5135, 142.73 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015920", "mag": 1.75, "time": 1506821149880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.354833, 33.961167, 5.95 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axcn", "mag": 4.9, "time": 1506821107970, "felt": 24, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 140.5685, 36.9167, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990780", "mag": 2.5, "time": 1506821107760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -169.8117, 51.8357, 61.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015912", "mag": 1.0, "time": 1506820492420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.119167, 33.9365, 14.07 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990779", "mag": 1.3, "time": 1506819992776, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.8841, 57.2184, 46.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990778", "mag": 1.0, "time": 1506819499573, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.4019, 63.1122, 97.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902491", "mag": 1.79, "time": 1506819103020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.939, 37.635333, 5.76 ] } }, +{ "type": "Feature", "properties": { "id": "ak16966268", "mag": 1.8, "time": 1506818601975, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.9252, 60.1498, 112.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16966264", "mag": 1.5, "time": 1506818511725, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4432, 51.7288, 13.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16966263", "mag": 2.1, "time": 1506818242272, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.7041, 52.7581, 14.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990774", "mag": 1.5, "time": 1506818099252, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4546, 51.7076, 6.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16990772", "mag": 2.7, "time": 1506817440647, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -169.6939, 51.8802, 15.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axc3", "mag": 4.5, "time": 1506817163710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 126.9456, 7.2071, 68.13 ] } }, +{ "type": "Feature", "properties": { "id": "ak16965336", "mag": 1.9, "time": 1506816635445, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.9899, 60.0896, 71.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16965329", "mag": 1.2, "time": 1506816385660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3486, 64.9885, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axbx", "mag": 4.3, "time": 1506816328880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -169.9474, 51.9828, 27.38 ] } }, +{ "type": "Feature", "properties": { "id": "hv61928136", "mag": 2.02, "time": 1506816129630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.123672, 19.313999, 2.22 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250512", "mag": 2.38, "time": 1506814998100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.459167, 42.663667, 2.14 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axbj", "mag": 3.2, "time": 1506814776660, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4566, 42.652, 6.15 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axba", "mag": 2.8, "time": 1506814745510, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4606, 42.6545, 4.98 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axb6", "mag": 2.7, "time": 1506814557760, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.473, 42.6754, 3.19 ] } }, +{ "type": "Feature", "properties": { "id": "ak16964389", "mag": 1.2, "time": 1506813911112, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.5092, 62.3699, 51.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015880", "mag": 1.87, "time": 1506813831910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.455333, 34.324167, 2.96 ] } }, +{ "type": "Feature", "properties": { "id": "us2000axas", "mag": 5.5, "time": 1506813329570, "felt": null, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 128.5426, 3.9405, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16964388", "mag": 1.6, "time": 1506812976279, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.5291, 59.2674, 85.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989805", "mag": 1.4, "time": 1506812398891, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.7509, 60.014, 105.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16964387", "mag": 1.0, "time": 1506812112182, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.1116, 62.3522, 7.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16964380", "mag": 1.0, "time": 1506811899089, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.6933, 62.6659, 6.2 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607730", "mag": 1.0, "time": 1506811774166, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.9049, 37.2915, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607738", "mag": 1.0, "time": 1506811292528, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.8999, 37.2878, 3.1 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607737", "mag": 1.1, "time": 1506811240125, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.9056, 37.279, 6.4 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607728", "mag": 1.1, "time": 1506811230164, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.9061, 37.2885, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250442", "mag": 2.43, "time": 1506810599500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4515, 42.661, 2.56 ] } }, +{ "type": "Feature", "properties": { "id": "ak16963468", "mag": 1.2, "time": 1506810291866, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.5204, 63.352, 8.1 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607721", "mag": 1.4, "time": 1506807445148, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.6755, 40.2201, 8.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16963443", "mag": 1.1, "time": 1506806484011, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3476, 61.4217, 25.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16963413", "mag": 2.3, "time": 1506806152613, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -144.0067, 60.9307, 14.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16962501", "mag": 4.2, "time": 1506806106026, "felt": 17, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ -152.2422, 59.621, 83.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989798", "mag": 1.1, "time": 1506805696616, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.7955, 61.7318, 98.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax9r", "mag": 4.7, "time": 1506805651800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 139.9751, 27.653, 485.8 ] } }, +{ "type": "Feature", "properties": { "id": "uw61335981", "mag": 1.82, "time": 1506805100680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.056833, 48.412333, 50.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902471", "mag": 2.5, "time": 1506804691550, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.2745, 38.558167, 6.21 ] } }, +{ "type": "Feature", "properties": { "id": "nc71107604", "mag": 0.96, "time": 1506804690650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.780167, 35.5105, 3.92 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015856", "mag": 1.0, "time": 1506804008820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.791, 33.512, 6.24 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax9d", "mag": 4.1, "time": 1506803686610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 122.7108, -8.0939, 216.64 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax9h", "mag": 3.5, "time": 1506803627030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -68.5125, 17.7855, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "hv61927906", "mag": 3.49, "time": 1506803617560, "felt": 9, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.469, 19.209667, 35.947 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax99", "mag": 4.7, "time": 1506802488710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 143.8145, 21.6564, 64.59 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015848", "mag": 1.38, "time": 1506802371860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.363167, 33.357333, 10.38 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902466", "mag": 1.77, "time": 1506801988210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.781, 38.796667, 3.44 ] } }, +{ "type": "Feature", "properties": { "id": "ak16962490", "mag": 1.1, "time": 1506800090127, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.1783, 59.7871, 69.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16962484", "mag": 1.5, "time": 1506799366659, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6852, 63.5864, 3.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607710", "mag": 1.2, "time": 1506799171022, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.1362, 38.2888, 10.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16962480", "mag": 3.0, "time": 1506798820424, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.1572, 55.8639, 11.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989794", "mag": 1.9, "time": 1506798785904, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -176.2132, 52.0688, 7.4 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258414", "mag": 1.87, "time": 1506798465250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.525333, 46.872833, 11.78 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax8b", "mag": 2.5, "time": 1506797682590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4618, 42.6659, 3.65 ] } }, +{ "type": "Feature", "properties": { "id": "ak16962476", "mag": 1.4, "time": 1506797627539, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.5093, 61.3123, 6.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16961588", "mag": 1.1, "time": 1506797036668, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.7901, 63.2441, 12.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0d3", "mag": 4.1, "time": 1506796297940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.8027, 15.4984, 19.41 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015776", "mag": 1.28, "time": 1506796206280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.89, 34.349167, 2.93 ] } }, +{ "type": "Feature", "properties": { "id": "ak16961586", "mag": 2.0, "time": 1506795961720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.8619, 51.4801, 41.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16961585", "mag": 1.1, "time": 1506795458511, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.5581, 61.5616, 72.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015752", "mag": 1.52, "time": 1506795424490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.160667, 34.4365, 4.43 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax7s", "mag": 4.8, "time": 1506795349220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9189, 16.1602, 51.93 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904876", "mag": 1.25, "time": 1506795206390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.484167, 40.699167, 11.98 ] } }, +{ "type": "Feature", "properties": { "id": "ak16961582", "mag": 1.1, "time": 1506794436503, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.6079, 60.1354, 9.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16961580", "mag": 1.1, "time": 1506794299451, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.5942, 60.1565, 7.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16961575", "mag": 1.6, "time": 1506793157002, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.119, 51.4689, 25.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax76", "mag": 4.9, "time": 1506789944160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -90.9767, 1.0533, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902376", "mag": 1.84, "time": 1506788771420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.8085, 38.817833, 3.12 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902381", "mag": 1.19, "time": 1506788628860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.3415, 37.8225, -0.07 ] } }, +{ "type": "Feature", "properties": { "id": "ak16960680", "mag": 2.9, "time": 1506788491228, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 179.9778, 51.4147, 57.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989782", "mag": 1.1, "time": 1506788345464, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.7866, 57.4545, 53.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902371", "mag": 1.16, "time": 1506786770930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.691, 38.7405, 1.44 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax6w", "mag": 2.6, "time": 1506785489440, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.5446, 36.2305, 5.63 ] } }, +{ "type": "Feature", "properties": { "id": "ak16959801", "mag": 1.0, "time": 1506785312713, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7001, 61.542, 58.2 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258389", "mag": 1.27, "time": 1506783781070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.531167, 46.8685, 11.42 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015696", "mag": 2.28, "time": 1506783542670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.492667, 34.216, 5.74 ] } }, +{ "type": "Feature", "properties": { "id": "ak16959795", "mag": 1.6, "time": 1506783111232, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.5985, 59.916, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902346", "mag": 1.53, "time": 1506782817930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.249667, 37.864833, 5.03 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902336", "mag": 1.34, "time": 1506782106540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.819833, 37.603833, 4.12 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015672", "mag": 1.46, "time": 1506781658250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.2715, 34.059333, 15.26 ] } }, +{ "type": "Feature", "properties": { "id": "uw61335861", "mag": 1.05, "time": 1506780581040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.452333, 48.382667, 22.31 ] } }, +{ "type": "Feature", "properties": { "id": "hv61927751", "mag": 2.29, "time": 1506780487200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.627833, 19.405333, 3.602 ] } }, +{ "type": "Feature", "properties": { "id": "ak16958915", "mag": 1.1, "time": 1506779690755, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.5599, 60.3017, 2.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16958913", "mag": 1.2, "time": 1506779388174, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.6949, 63.8592, 1.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989774", "mag": 1.1, "time": 1506778517082, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.4836, 62.981, 94.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015648", "mag": 1.53, "time": 1506777358020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.461667, 34.329167, 3.88 ] } }, +{ "type": "Feature", "properties": { "id": "ak16958909", "mag": 1.8, "time": 1506777347886, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -159.2124, 67.8158, 1.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015640", "mag": 2.0, "time": 1506777335770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.658167, 31.867, 1.78 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015616", "mag": 1.28, "time": 1506776191250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.768833, 33.326833, 12.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16958907", "mag": 1.2, "time": 1506775842000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4069, 62.3275, 86.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902306", "mag": 1.41, "time": 1506775748110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.82, 37.605333, 4.33 ] } }, +{ "type": "Feature", "properties": { "id": "ak16958905", "mag": 2.0, "time": 1506775349934, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -163.7202, 67.3687, 4.2 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607651", "mag": 1.2, "time": 1506775034180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8976, 38.3688, 7.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16958026", "mag": 2.8, "time": 1506774114627, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -163.7286, 67.3815, 8.4 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250312", "mag": 2.59, "time": 1506774047790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.635, 37.764167, 13.14 ] } }, +{ "type": "Feature", "properties": { "id": "ak16958023", "mag": 1.6, "time": 1506773722633, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6494, 63.1022, 115.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989768", "mag": 1.6, "time": 1506773709105, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.8697, 59.0106, 105.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902286", "mag": 1.55, "time": 1506773378420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.898833, 37.522667, 12.57 ] } }, +{ "type": "Feature", "properties": { "id": "ld60143701", "mag": 0.98, "time": 1506773153350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -74.5095, 40.809333, 11.51 ] } }, +{ "type": "Feature", "properties": { "id": "ak16958020", "mag": 1.2, "time": 1506771142867, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.0654, 62.1893, 8.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16957154", "mag": 1.4, "time": 1506770413805, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.3117, 61.0872, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015552", "mag": 1.58, "time": 1506769732230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.155, 34.5615, 2.13 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989763", "mag": 1.5, "time": 1506768979985, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.1722, 60.0493, 117.8 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250297", "mag": 1.97, "time": 1506768169440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4255, 42.547, 7.49 ] } }, +{ "type": "Feature", "properties": { "id": "ak16957134", "mag": 1.5, "time": 1506768169245, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.9682, 61.4708, 39.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax5m", "mag": 5.2, "time": 1506767402460, "felt": null, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 128.7797, 1.8973, 37.67 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989760", "mag": 1.1, "time": 1506766077754, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.8184, 60.0072, 67.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902251", "mag": 1.22, "time": 1506766057090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.800833, 38.792667, 2.88 ] } }, +{ "type": "Feature", "properties": { "id": "ak16956252", "mag": 1.6, "time": 1506765146662, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3164, 61.6465, 25.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax55", "mag": 4.4, "time": 1506764918800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0971, 15.3765, 35.53 ] } }, +{ "type": "Feature", "properties": { "id": "ak16956250", "mag": 3.1, "time": 1506764602367, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.3876, 51.6362, 13.1 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250277", "mag": 1.1, "time": 1506764348800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.411333, 38.962833, -1.36 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902211", "mag": 2.24, "time": 1506763678540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.1355, 37.688333, 25.77 ] } }, +{ "type": "Feature", "properties": { "id": "ak16955383", "mag": 2.0, "time": 1506763079790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.7222, 59.2509, 16.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16955380", "mag": 1.1, "time": 1506762584802, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.0664, 61.8814, 35.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902196", "mag": 1.37, "time": 1506761418100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7435, 38.788, 0.74 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax4r", "mag": 2.5, "time": 1506761330980, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.5543, 36.2286, 1.38 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015488", "mag": 1.48, "time": 1506761301510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.3055, 33.255167, 10.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015480", "mag": 1.54, "time": 1506760683740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.638333, 33.165167, 2.88 ] } }, +{ "type": "Feature", "properties": { "id": "ak16955371", "mag": 2.5, "time": 1506760322340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -179.9144, 51.2732, 19.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902186", "mag": 1.08, "time": 1506759358360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.750832, 38.806835, 0.69 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902176", "mag": 1.52, "time": 1506758934270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.270833, 39.463167, 6.67 ] } }, +{ "type": "Feature", "properties": { "id": "ak16955365", "mag": 2.3, "time": 1506758896299, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -173.4581, 50.7723, 29.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16955363", "mag": 1.2, "time": 1506758873795, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2563, 61.2042, 65.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902161", "mag": 1.43, "time": 1506758269830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.820833, 37.604167, 3.89 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902151", "mag": 1.08, "time": 1506757752200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.095167, 36.564333, 8.65 ] } }, +{ "type": "Feature", "properties": { "id": "ak16954507", "mag": 1.7, "time": 1506757551919, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -176.4734, 51.7808, 63.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16954502", "mag": 1.5, "time": 1506757337943, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.7203, 60.1564, 96.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16954501", "mag": 1.2, "time": 1506757146790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.0463, 62.4859, 12.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16954494", "mag": 1.2, "time": 1506755657374, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.4986, 59.9398, 15.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989746", "mag": 1.4, "time": 1506755147399, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -176.4214, 51.6622, 47.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902146", "mag": 1.49, "time": 1506754443300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7965, 38.821167, 2.97 ] } }, +{ "type": "Feature", "properties": { "id": "ak16953640", "mag": 1.8, "time": 1506754020475, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3389, 63.5229, 14.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015432", "mag": 1.45, "time": 1506753848290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.784, 34.512167, 18.77 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902141", "mag": 1.71, "time": 1506753528720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9575, 37.590333, -0.13 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax3z", "mag": 5.0, "time": 1506753276470, "felt": 12, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 178.7893, -37.146, 51.02 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax3x", "mag": 4.0, "time": 1506752562800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.1802, 15.1606, 44.16 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax3v", "mag": 5.5, "time": 1506752076970, "felt": 45, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 105.0015, 32.3196, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902116", "mag": 1.62, "time": 1506750865330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.599667, 37.407833, 9.53 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015368", "mag": 1.67, "time": 1506750508810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.076333, 36.188833, 2.55 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258359", "mag": 1.02, "time": 1506750398880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -113.9725, 47.5955, 16.81 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax3j", "mag": 2.7, "time": 1506750040910, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.2913, 46.8038, 7.79 ] } }, +{ "type": "Feature", "properties": { "id": "ak16952767", "mag": 1.8, "time": 1506749904921, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.3454, 60.3536, 81.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16952766", "mag": 2.3, "time": 1506749189648, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -169.3954, 52.6671, 7.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax39", "mag": 4.5, "time": 1506748759440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 146.5825, -6.071, 46.79 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902081", "mag": 1.59, "time": 1506748525170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.82, 37.603833, 3.81 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989740", "mag": 1.2, "time": 1506747601510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7455, 63.2374, 127.9 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250227", "mag": 1.55, "time": 1506747254170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.416167, 42.576, 7.87 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989738", "mag": 2.1, "time": 1506746345789, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -176.3938, 52.2402, 166.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax2y", "mag": 2.0, "time": 1506744973730, "felt": 15, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -103.5373, 31.4264, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax2z", "mag": 4.2, "time": 1506744770640, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 56.8179, 27.8699, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16951924", "mag": 1.9, "time": 1506744732618, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0884, 59.736, 45.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72902041", "mag": 1.11, "time": 1506744250250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.833, 37.493667, -0.44 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989735", "mag": 1.2, "time": 1506741220731, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9578, 61.9828, 69.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16951083", "mag": 2.6, "time": 1506741030111, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.6653, 59.3044, 110.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989733", "mag": 1.9, "time": 1506739580500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.7167, 57.5293, 92.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax2n", "mag": 4.5, "time": 1506739554570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 136.7409, -3.3243, 53.79 ] } }, +{ "type": "Feature", "properties": { "id": "ak16951081", "mag": 1.2, "time": 1506738073140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.643, 59.7863, 2.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015232", "mag": 1.78, "time": 1506737478680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.242833, 34.689, 2.49 ] } }, +{ "type": "Feature", "properties": { "id": "nm60207556", "mag": 1.6, "time": 1506737274410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -89.540333, 36.441167, 8.74 ] } }, +{ "type": "Feature", "properties": { "id": "ak16951079", "mag": 1.0, "time": 1506737168134, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.6248, 59.7789, 3.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989730", "mag": 1.0, "time": 1506736917340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.3855, 61.2392, 35.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16951077", "mag": 2.7, "time": 1506736523109, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -175.4182, 51.6603, 65.4 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607629", "mag": 1.3, "time": 1506736488217, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.2269, 38.6102, 7.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989728", "mag": 1.8, "time": 1506734962617, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.4354, 59.672, 120.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax2c", "mag": 4.2, "time": 1506734849800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.1267, 15.2552, 35.18 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015192", "mag": 1.59, "time": 1506734841110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.231333, 34.69, 2.26 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901986", "mag": 1.53, "time": 1506733264430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.820667, 37.604833, 4.25 ] } }, +{ "type": "Feature", "properties": { "id": "ak16950243", "mag": 1.5, "time": 1506732735872, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.8027, 59.8685, 4.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989726", "mag": 1.2, "time": 1506732275435, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.7993, 62.6213, 100.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b217", "mag": 4.4, "time": 1506731641840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.5238, -17.429, 578.55 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901976", "mag": 1.18, "time": 1506731621270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.821, 37.608667, 4.18 ] } }, +{ "type": "Feature", "properties": { "id": "ak16950242", "mag": 1.2, "time": 1506731391196, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.6362, 63.7125, 120.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989723", "mag": 1.7, "time": 1506730448510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.6879, 60.1242, 106.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015160", "mag": 1.92, "time": 1506730343820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.0465, 33.1715, 3.57 ] } }, +{ "type": "Feature", "properties": { "id": "ak16950224", "mag": 2.7, "time": 1506729701559, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.9689, 62.8827, 10.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015152", "mag": 2.71, "time": 1506729570740, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.046167, 33.172833, 9.13 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989254", "mag": 1.6, "time": 1506729481572, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.2839, 51.9212, 67.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16950219", "mag": 1.3, "time": 1506729013003, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.9672, 64.4141, 9.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16950216", "mag": 1.6, "time": 1506728300228, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.1933, 61.9028, 3.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax17", "mag": 4.7, "time": 1506727132760, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 120.696, 13.6996, 135.75 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949390", "mag": 2.0, "time": 1506727039137, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.6767, 61.5138, 15.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949386", "mag": 1.2, "time": 1506726713734, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3628, 64.9795, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901936", "mag": 1.7, "time": 1506726391160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.822, 37.604667, 4.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015128", "mag": 1.14, "time": 1506725917420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.794167, 33.499833, 4.55 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax0h", "mag": 4.3, "time": 1506725523560, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -72.9693, 6.7514, 162.39 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901926", "mag": 1.27, "time": 1506725219450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.819667, 37.6045, 3.92 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989247", "mag": 1.4, "time": 1506725194385, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2194, 60.3483, 70.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901921", "mag": 1.68, "time": 1506724972140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.7985, 38.0515, 10.15 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0b0", "mag": 4.2, "time": 1506724750370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.7775, 14.8225, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awzq", "mag": 4.2, "time": 1506724590080, "felt": 7, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -72.1967, -31.7027, 34.99 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250212", "mag": 1.71, "time": 1506723678770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.33, 44.419, 8.43 ] } }, +{ "type": "Feature", "properties": { "id": "ak16948452", "mag": 1.0, "time": 1506723638356, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.5236, 61.0736, 4.6 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250207", "mag": 0.97, "time": 1506723591620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.331, 44.419667, 7.85 ] } }, +{ "type": "Feature", "properties": { "id": "ak16948450", "mag": 2.2, "time": 1506723243356, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.3899, 51.6225, 6.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989243", "mag": 1.8, "time": 1506723039650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.6224, 58.8526, 127.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015088", "mag": 2.26, "time": 1506722552150, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.2355, 34.1175, 22.24 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awz1", "mag": 4.9, "time": 1506721850800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0878, 15.2008, 58.14 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awyk", "mag": 3.0, "time": 1506721368710, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -126.71, 43.4329, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awyj", "mag": 2.5, "time": 1506721170670, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -96.8727, 36.4662, 8.25 ] } }, +{ "type": "Feature", "properties": { "id": "ak16948433", "mag": 1.1, "time": 1506720878279, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3481, 63.5145, 7.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015064", "mag": 1.38, "time": 1506720751740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.9775, 33.998333, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901896", "mag": 1.79, "time": 1506720632350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.822, 37.604667, 3.82 ] } }, +{ "type": "Feature", "properties": { "id": "ak16948427", "mag": 2.1, "time": 1506720336314, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.3588, 61.6517, 20.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901891", "mag": 2.87, "time": 1506720104700, "felt": 12, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.352667, 38.643167, 5.77 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax7e", "mag": 2.5, "time": 1506719402880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.5572, 49.4225, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awxt", "mag": 4.4, "time": 1506718802820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.8406, 16.1453, 55.29 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901871", "mag": 1.92, "time": 1506717945880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.878667, 37.535, 2.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015016", "mag": 1.05, "time": 1506717237070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.142333, 33.336167, -0.44 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awx6", "mag": 4.7, "time": 1506717060150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.3377, 14.7629, 21.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901856", "mag": 1.02, "time": 1506716541140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.722, 38.777668, 1.65 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258329", "mag": 1.68, "time": 1506716143860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.210167, 46.588333, 0.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989238", "mag": 1.6, "time": 1506715318085, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.6762, 51.2251, 46.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci38015000", "mag": 1.05, "time": 1506715194050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.174667, 33.223167, -0.31 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989237", "mag": 1.3, "time": 1506715107803, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4109, 51.6654, 14.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989236", "mag": 1.8, "time": 1506714300796, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -173.0656, 51.6073, 13.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16946778", "mag": 1.8, "time": 1506713921345, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0358, 59.8156, 103.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awvi", "mag": 4.7, "time": 1506713408290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.8244, 14.6951, 25.26 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awvc", "mag": 5.3, "time": 1506713101350, "felt": 5, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 160.0808, 53.2159, 47.81 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901811", "mag": 1.13, "time": 1506712684050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.839833, 37.5695, 1.15 ] } }, +{ "type": "Feature", "properties": { "id": "ci38014936", "mag": 1.22, "time": 1506711284740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.962833, 36.582167, 5.17 ] } }, +{ "type": "Feature", "properties": { "id": "ak16945947", "mag": 1.1, "time": 1506711226973, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.7372, 61.7159, 11.2 ] } }, +{ "type": "Feature", "properties": { "id": "uw61335536", "mag": 1.21, "time": 1506711131520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.5445, 46.492667, -1.15 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901801", "mag": 1.03, "time": 1506711093580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.840332, 38.841, 1.28 ] } }, +{ "type": "Feature", "properties": { "id": "ci38014904", "mag": 1.27, "time": 1506710840540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.351833, 35.050333, -1.01 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901786", "mag": 1.25, "time": 1506710565410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.638, 38.771, 3.08 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901781", "mag": 1.14, "time": 1506710562310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.813333, 37.477, 10.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax1j", "mag": 2.6, "time": 1506708957540, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -126.9812, 40.4991, 10.41 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250167", "mag": 1.43, "time": 1506708811550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.408333, 42.627833, 0.01 ] } }, +{ "type": "Feature", "properties": { "id": "ak16945940", "mag": 2.2, "time": 1506708598408, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.1805, 65.8694, 11.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awu0", "mag": 4.4, "time": 1506708535930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -71.7041, -29.9428, 24.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989230", "mag": 1.2, "time": 1506708266694, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.5133, 51.924, 29.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901741", "mag": 0.97, "time": 1506707146210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.823167, 37.608833, 3.97 ] } }, +{ "type": "Feature", "properties": { "id": "ak16945938", "mag": 1.3, "time": 1506706984307, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -161.5563, 65.3108, 1.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16945133", "mag": 1.4, "time": 1506706312872, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.5157, 60.0338, 76.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16945129", "mag": 1.8, "time": 1506705516485, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.4094, 62.2086, 43.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901691", "mag": 1.19, "time": 1506705001740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.819833, 37.604, 4.23 ] } }, +{ "type": "Feature", "properties": { "id": "ak16945122", "mag": 2.7, "time": 1506704480054, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.3979, 51.6138, 9.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16945116", "mag": 1.6, "time": 1506703818483, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7333, 62.8722, 95.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901686", "mag": 1.37, "time": 1506703671060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.763167, 38.815, 1.59 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989222", "mag": 1.3, "time": 1506703480244, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.9223, 60.0784, 5.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aws4", "mag": 4.2, "time": 1506703454020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.2978, -24.5018, 178.46 ] } }, +{ "type": "Feature", "properties": { "id": "ak16945111", "mag": 1.4, "time": 1506703443591, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.3415, 60.1469, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aws9", "mag": 2.8, "time": 1506703434610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.561, 46.8309, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16945098", "mag": 2.9, "time": 1506703414975, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -176.2265, 52.0599, 4.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901676", "mag": 1.08, "time": 1506702827030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8685, 37.573667, 2.96 ] } }, +{ "type": "Feature", "properties": { "id": "ci38014752", "mag": 1.38, "time": 1506702364640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.9525, 33.161667, 8.71 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901666", "mag": 2.1, "time": 1506702098440, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.822, 37.604167, 4.23 ] } }, +{ "type": "Feature", "properties": { "id": "hv61926636", "mag": 2.18, "time": 1506702014920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.601833, 20.052667, 34.47 ] } }, +{ "type": "Feature", "properties": { "id": "ak16944301", "mag": 1.2, "time": 1506702004530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.4859, 61.9357, 38.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awn9", "mag": 4.6, "time": 1506701320270, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 30.6565, 36.9513, 89.38 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901651", "mag": 1.66, "time": 1506701302480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.628333, 36.892667, -0.13 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awp8", "mag": 5.0, "time": 1506701291670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 143.8294, 21.3911, 69.37 ] } }, +{ "type": "Feature", "properties": { "id": "ak16944298", "mag": 1.9, "time": 1506700558070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.3591, 59.6184, 107.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16944296", "mag": 1.5, "time": 1506699999652, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.347, 60.6887, 39.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16944295", "mag": 2.3, "time": 1506699741265, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.4266, 51.6803, 2.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16944283", "mag": 3.0, "time": 1506699614700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.523, 51.6975, 12.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989214", "mag": 1.4, "time": 1506699333969, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.5572, 51.8006, 17.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16944280", "mag": 1.6, "time": 1506699330322, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.4554, 63.4968, 4.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awju", "mag": 4.4, "time": 1506698634990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.674, 15.7931, 74.04 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901616", "mag": 1.45, "time": 1506698546300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.190833, 36.066, 9.01 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901611", "mag": 1.16, "time": 1506698374110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.820167, 37.606167, 4.24 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250142", "mag": 1.31, "time": 1506698139210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.502167, 42.0255, -0.68 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989212", "mag": 1.5, "time": 1506697780188, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.1692, 61.0412, 92.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901601", "mag": 1.58, "time": 1506697356900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8215, 37.603833, 3.81 ] } }, +{ "type": "Feature", "properties": { "id": "ak16944278", "mag": 1.3, "time": 1506696524699, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.2498, 63.4064, 80.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16943485", "mag": 1.7, "time": 1506695993154, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.7332, 58.8106, 5.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16943478", "mag": 1.7, "time": 1506695477590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.7502, 58.8134, 7.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awj3", "mag": 2.5, "time": 1506695343600, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.0981, 36.3324, 6.543 ] } }, +{ "type": "Feature", "properties": { "id": "ak16943471", "mag": 2.5, "time": 1506695221683, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.9597, 58.9824, 104.1 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250137", "mag": 1.65, "time": 1506694436450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.506667, 42.031167, 2.68 ] } }, +{ "type": "Feature", "properties": { "id": "ak16943466", "mag": 1.3, "time": 1506694161233, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3879, 63.5817, 1.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989205", "mag": 2.0, "time": 1506693991548, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -176.2136, 52.0676, 4.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901566", "mag": 2.08, "time": 1506693960730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.862333, 37.5625, 4.47 ] } }, +{ "type": "Feature", "properties": { "id": "ak16943439", "mag": 1.3, "time": 1506693558920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.0206, 61.729, 33.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci38014568", "mag": 2.51, "time": 1506693023860, "felt": 13, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.270167, 33.67, 4.47 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awib", "mag": 5.0, "time": 1506692997440, "felt": 13, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 67.9437, 39.8728, 20.04 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901551", "mag": 1.74, "time": 1506692955010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.821167, 37.605667, 4.05 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901546", "mag": 2.76, "time": 1506692724780, "felt": 8, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.822, 37.606167, 4.07 ] } }, +{ "type": "Feature", "properties": { "id": "ak16942648", "mag": 1.5, "time": 1506692473989, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.3697, 60.1847, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250132", "mag": 1.79, "time": 1506692243980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.431, 42.543833, 7.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258279", "mag": 1.06, "time": 1506691959070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.531833, 46.8625, 13.38 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901536", "mag": 1.82, "time": 1506691724930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.821, 37.605667, 4.02 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607504", "mag": 1.8, "time": 1506690215490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.7002, 37.7048, 16.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16942645", "mag": 2.8, "time": 1506689890335, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -176.2102, 52.0495, 4.8 ] } }, +{ "type": "Feature", "properties": { "id": "hv61926461", "mag": 1.62, "time": 1506689375520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.457667, 19.1075, 28.777 ] } }, +{ "type": "Feature", "properties": { "id": "ci38014488", "mag": 1.71, "time": 1506688966950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.030167, 36.589833, 2.83 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250122", "mag": 1.68, "time": 1506688495310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.410833, 42.548333, 8.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci38014464", "mag": 1.51, "time": 1506688363340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.292833, 33.924, 11.12 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250117", "mag": 1.2, "time": 1506688147640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.451, 42.651167, 3.75 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607501", "mag": 1.5, "time": 1506687351344, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.1244, 38.2711, 14.1 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258269", "mag": 1.01, "time": 1506686927230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -113.712667, 47.670333, 12.54 ] } }, +{ "type": "Feature", "properties": { "id": "hv61926436", "mag": 2.78, "time": 1506686302190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.030667, 19.839833, 12.705 ] } }, +{ "type": "Feature", "properties": { "id": "ak16941853", "mag": 1.9, "time": 1506685697166, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.2959, 57.1271, 73.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awh4", "mag": 4.5, "time": 1506685520260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0117, 15.1312, 54.94 ] } }, +{ "type": "Feature", "properties": { "id": "ak16941849", "mag": 1.4, "time": 1506685238756, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.2101, 65.8679, 9.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awh2", "mag": 3.2, "time": 1506684953300, "felt": 21, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -105.3739, 35.8708, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901446", "mag": 1.81, "time": 1506683864270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8685, 37.5745, 2.94 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989195", "mag": 2.8, "time": 1506683238639, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -170.2168, 53.4134, 215.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16941846", "mag": 2.8, "time": 1506683013276, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4342, 51.6411, 13.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci38014408", "mag": 1.09, "time": 1506682934740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.248167, 34.684167, 3.67 ] } }, +{ "type": "Feature", "properties": { "id": "ci38014400", "mag": 1.41, "time": 1506682423780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.6475, 32.295833, 17.59 ] } }, +{ "type": "Feature", "properties": { "id": "uw61335391", "mag": 1.31, "time": 1506682259150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.713833, 45.779, 4.47 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607493", "mag": 1.3, "time": 1506681999912, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.1157, 38.2921, 8.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awgp", "mag": 4.0, "time": 1506681630910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -168.1308, 51.5953, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38014376", "mag": 2.27, "time": 1506680323320, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.236167, 34.686333, 2.51 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901411", "mag": 1.72, "time": 1506679482310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.821833, 37.606833, 4.18 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250092", "mag": 1.5, "time": 1506678952480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.408833, 42.556667, 7.57 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901396", "mag": 1.23, "time": 1506677982920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.0275, 36.556333, 6.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci38014304", "mag": 1.52, "time": 1506677845800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.798333, 33.502667, 4.26 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250087", "mag": 1.18, "time": 1506677776470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.772667, 41.2685, 12.53 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awgf", "mag": 4.7, "time": 1506677102490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 143.7467, 21.3618, 39.87 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989192", "mag": 1.2, "time": 1506676690210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.7405, 63.338, 95.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci38014288", "mag": 1.53, "time": 1506676635710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.671, 33.215333, 3.29 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901376", "mag": 1.15, "time": 1506676399250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.721832, 38.776001, 1.56 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901366", "mag": 1.25, "time": 1506676178310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.838167, 37.489833, 1.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607489", "mag": 1.9, "time": 1506676166910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.2245, 38.4923, 40.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989191", "mag": 1.8, "time": 1506675279572, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.0102, 58.492, 85.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989190", "mag": 1.3, "time": 1506674952846, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.1298, 60.9057, 47.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awfl", "mag": 4.4, "time": 1506674809710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.929, 14.9856, 43.22 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250082", "mag": 1.77, "time": 1506674053050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.7785, 38.186667, 4.92 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989188", "mag": 1.8, "time": 1506673945397, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -176.291, 51.5518, 1.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16940268", "mag": 1.1, "time": 1506673847917, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1687, 63.2488, 4.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901291", "mag": 1.25, "time": 1506673221590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.898667, 37.523167, 12.92 ] } }, +{ "type": "Feature", "properties": { "id": "ak16940267", "mag": 1.0, "time": 1506672847451, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5017, 66.1069, 17.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci38014192", "mag": 1.18, "time": 1506671965070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.4335, 34.163833, 7.61 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awf5", "mag": 4.2, "time": 1506671826720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 90.3467, 33.9272, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607584", "mag": 1.4, "time": 1506671521193, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.1177, 38.2758, 11.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci38014184", "mag": 2.46, "time": 1506671466000, "felt": 7, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.978833, 33.994167, 4.88 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607484", "mag": 1.8, "time": 1506671441804, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.1188, 38.2704, 11.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901256", "mag": 1.15, "time": 1506670814700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.8105, 38.808833, 0.67 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901241", "mag": 1.25, "time": 1506670284580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.989667, 36.427667, 2.31 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901231", "mag": 1.07, "time": 1506669441060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.540833, 37.406667, 8.01 ] } }, +{ "type": "Feature", "properties": { "id": "uw61335361", "mag": 1.94, "time": 1506668594230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.733667, 47.824, 24.16 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awej", "mag": 4.2, "time": 1506668295660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 55.3123, 28.2886, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901196", "mag": 0.96, "time": 1506668052570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.571833, 36.012667, 3.67 ] } }, +{ "type": "Feature", "properties": { "id": "ak16940266", "mag": 1.2, "time": 1506668048758, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.5877, 62.1976, 22.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901186", "mag": 1.14, "time": 1506667805720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.848167, 37.6535, 2.83 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901176", "mag": 1.25, "time": 1506667100210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.838333, 37.506167, 0.64 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901171", "mag": 2.27, "time": 1506666779210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.835333, 37.507167, -1.01 ] } }, +{ "type": "Feature", "properties": { "id": "ak16940265", "mag": 1.4, "time": 1506666562961, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.3945, 61.6303, 33.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16940263", "mag": 1.0, "time": 1506666497414, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.1712, 62.2695, 52.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901166", "mag": 1.28, "time": 1506666202970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.834167, 37.5065, 0.53 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awe6", "mag": 2.6, "time": 1506666160200, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -96.6816, 35.8653, 6.569 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607469", "mag": 1.0, "time": 1506665961601, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.5308, 38.52, 7.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci38014104", "mag": 1.28, "time": 1506665954550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.982833, 33.1725, 3.45 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989182", "mag": 1.1, "time": 1506665936336, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.485, 62.1641, 22.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901156", "mag": 2.23, "time": 1506665326530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8385, 37.505167, 1.37 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901146", "mag": 3.34, "time": 1506665130490, "felt": 5, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8355, 37.5055, 1.65 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989181", "mag": 1.9, "time": 1506664620963, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -168.5107, 52.4839, 24.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901116", "mag": 1.16, "time": 1506664498090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.824833, 37.605667, 4.02 ] } }, +{ "type": "Feature", "properties": { "id": "ak16939483", "mag": 1.1, "time": 1506663985990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.9358, 61.1521, 6.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901106", "mag": 1.19, "time": 1506663736480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.78717, 38.829334, 1.02 ] } }, +{ "type": "Feature", "properties": { "id": "nm60207436", "mag": 1.74, "time": 1506663708600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -89.653833, 36.539667, 9.66 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awdv", "mag": 4.5, "time": 1506663030100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -179.5233, -24.0812, 546.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16939475", "mag": 1.7, "time": 1506662432885, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8708, 60.1234, 43.7 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250077", "mag": 1.14, "time": 1506662404800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.55, 41.1085, 19.56 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901046", "mag": 1.46, "time": 1506661869950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.846833, 37.647833, 3.02 ] } }, +{ "type": "Feature", "properties": { "id": "ci38013856", "mag": 2.0, "time": 1506660542280, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.978, 33.995, 4.89 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989177", "mag": 1.2, "time": 1506660008320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.4686, 63.102, 104.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16945113", "mag": 2.3, "time": 1506659927913, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.0654, 53.6407, 46.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awd5", "mag": 5.0, "time": 1506659595610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.1021, 14.8894, 24.04 ] } }, +{ "type": "Feature", "properties": { "id": "nc72901021", "mag": 1.62, "time": 1506659436560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.826833, 38.814, 1.76 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awd1", "mag": 3.0, "time": 1506658713990, "felt": 5, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -96.6968, 35.8549, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258249", "mag": 2.26, "time": 1506658662520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.514, 46.840833, 13.41 ] } }, +{ "type": "Feature", "properties": { "id": "ci38013816", "mag": 1.03, "time": 1506658457830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.02, 34.015, 13.93 ] } }, +{ "type": "Feature", "properties": { "id": "ak16938672", "mag": 1.1, "time": 1506657671332, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.311, 64.8546, 17.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awcv", "mag": 5.6, "time": 1506657622320, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0465, 14.9039, 21.66 ] } }, +{ "type": "Feature", "properties": { "id": "ak16945097", "mag": 2.0, "time": 1506657417279, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.3696, 53.5031, 41.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900986", "mag": 1.05, "time": 1506657208460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.835833, 37.502333, -0.01 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70235973", "mag": 1.64, "time": 1506657154290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.887333, 37.201833, 5.03 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900981", "mag": 1.98, "time": 1506656801880, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.8045, 38.832333, 1.64 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900976", "mag": 1.12, "time": 1506656629400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.758667, 38.793499, 0.77 ] } }, +{ "type": "Feature", "properties": { "id": "ci38013768", "mag": 1.6, "time": 1506656062720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.976, 33.995833, 3.45 ] } }, +{ "type": "Feature", "properties": { "id": "ak16937888", "mag": 1.8, "time": 1506653782695, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9369, 62.1991, 64.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989171", "mag": 1.9, "time": 1506653188688, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 178.5129, 51.845, 110.0 ] } }, +{ "type": "Feature", "properties": { "id": "hv61925851", "mag": 0.95, "time": 1506653113010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.463667, 19.481, 6.56 ] } }, +{ "type": "Feature", "properties": { "id": "ci38013744", "mag": 1.0, "time": 1506653104110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.302333, 34.099, 15.05 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awce", "mag": 4.4, "time": 1506652310280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 141.7803, 35.9821, 42.36 ] } }, +{ "type": "Feature", "properties": { "id": "ci38013736", "mag": 2.07, "time": 1506652304260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.259833, 32.454333, 2.17 ] } }, +{ "type": "Feature", "properties": { "id": "ci38013720", "mag": 2.39, "time": 1506651375080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.569, 31.324, 4.82 ] } }, +{ "type": "Feature", "properties": { "id": "ci38013712", "mag": 1.12, "time": 1506651359620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.924833, 33.976167, 6.34 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607452", "mag": 1.0, "time": 1506651336185, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.1923, 35.5727, 11.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci38013704", "mag": 0.97, "time": 1506651243970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.7885, 33.494833, 5.39 ] } }, +{ "type": "Feature", "properties": { "id": "ci38013688", "mag": 1.05, "time": 1506650990920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.791167, 33.5105, 6.09 ] } }, +{ "type": "Feature", "properties": { "id": "ak16937883", "mag": 2.4, "time": 1506650514315, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.9834, 51.7396, 25.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900931", "mag": 1.16, "time": 1506649983200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.720497, 38.775501, 1.87 ] } }, +{ "type": "Feature", "properties": { "id": "ak16937869", "mag": 2.6, "time": 1506649468698, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8838, 61.8075, 66.1 ] } }, +{ "type": "Feature", "properties": { "id": "uu60013219", "mag": 1.32, "time": 1506648472160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.687, 41.150667, 12.61 ] } }, +{ "type": "Feature", "properties": { "id": "uu60250062", "mag": 2.53, "time": 1506648435990, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.936667, 38.921333, 10.59 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awbw", "mag": 4.5, "time": 1506648405500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -169.976, 52.0498, 29.97 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awbq", "mag": 4.9, "time": 1506648161110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -170.1717, 52.3421, 33.24 ] } }, +{ "type": "Feature", "properties": { "id": "ak16937823", "mag": 1.0, "time": 1506648034498, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.0631, 63.4906, 4.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989160", "mag": 1.6, "time": 1506646713769, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.579, 51.7059, 15.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900911", "mag": 1.15, "time": 1506646505210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.834333, 37.504, -0.73 ] } }, +{ "type": "Feature", "properties": { "id": "ci38013672", "mag": 2.61, "time": 1506646378780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.570333, 31.324667, 4.82 ] } }, +{ "type": "Feature", "properties": { "id": "ak16937047", "mag": 1.0, "time": 1506646107258, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4881, 63.0417, 2.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16937045", "mag": 1.9, "time": 1506646058692, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.135, 67.8468, 16.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900906", "mag": 1.03, "time": 1506645880090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.876831, 38.8405, 2.17 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900886", "mag": 1.63, "time": 1506645570060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.818333, 38.816667, 2.21 ] } }, +{ "type": "Feature", "properties": { "id": "ci38013656", "mag": 2.24, "time": 1506645489800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.313, 34.094167, 17.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci38013632", "mag": 1.51, "time": 1506645195410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.7955, 33.502667, 3.76 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900876", "mag": 1.03, "time": 1506644780060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.818, 37.470667, 1.87 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900871", "mag": 1.62, "time": 1506644672730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.585667, 37.234667, 6.49 ] } }, +{ "type": "Feature", "properties": { "id": "ak16937041", "mag": 1.3, "time": 1506644621941, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.3267, 62.8222, 57.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16937039", "mag": 1.7, "time": 1506644576562, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.2144, 60.0462, 13.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16937037", "mag": 1.1, "time": 1506644052798, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.3512, 58.196, 2.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989154", "mag": 1.6, "time": 1506643362489, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.3692, 51.6466, 12.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16937036", "mag": 1.4, "time": 1506643250597, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.7379, 61.4006, 18.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awbb", "mag": 4.9, "time": 1506643017480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 144.7489, 19.052, 30.59 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989677", "mag": 1.5, "time": 1506642839250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.8862, 61.8988, 105.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16936268", "mag": 1.2, "time": 1506642106483, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.9604, 62.3327, 42.9 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607431", "mag": 1.9, "time": 1506641437450, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.5187, 36.978, 7.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900841", "mag": 1.93, "time": 1506641348540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.821, 37.606667, 4.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900846", "mag": 1.13, "time": 1506641325970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.818833, 37.608333, 4.24 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904266", "mag": 0.96, "time": 1506641269180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.0985, 41.357, -1.69 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989674", "mag": 1.6, "time": 1506641141934, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.9034, 59.5213, 94.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awa2", "mag": 4.4, "time": 1506640604400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -175.6403, 51.5228, 41.23 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607821", "mag": 1.1, "time": 1506640364409, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9062, 38.3722, 8.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aw9p", "mag": 5.4, "time": 1506640275740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -179.7911, -24.8725, 440.96 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b1wl", "mag": 4.8, "time": 1506639694670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 127.5676, 1.0849, 4.38 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aw9e", "mag": 4.7, "time": 1506639688220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 133.3331, 2.9053, 15.04 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989671", "mag": 1.7, "time": 1506639639127, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.3134, 59.6717, 111.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16936241", "mag": 2.5, "time": 1506639635527, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.1768, 68.4586, 17.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900821", "mag": 1.1, "time": 1506639127150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.834833, 37.500333, -1.77 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aw90", "mag": 5.1, "time": 1506638831750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.5949, -34.0499, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aw8l", "mag": 4.3, "time": 1506638537770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 130.4998, -6.5326, 108.74 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900811", "mag": 2.32, "time": 1506638416610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.1135, 35.6885, 5.91 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900806", "mag": 1.35, "time": 1506638081190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.878833, 37.534, 2.41 ] } }, +{ "type": "Feature", "properties": { "id": "uw61335056", "mag": 1.84, "time": 1506638058160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.417833, 45.624333, -1.28 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258209", "mag": 1.37, "time": 1506637878310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.521333, 46.910833, 10.76 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935473", "mag": 1.9, "time": 1506637576311, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -158.5454, 67.5431, 1.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935469", "mag": 2.0, "time": 1506637236181, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.4826, 58.8115, 4.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989667", "mag": 2.0, "time": 1506636836791, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.4008, 59.8707, 143.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989666", "mag": 1.1, "time": 1506636594038, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2636, 62.56, 91.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900796", "mag": 1.35, "time": 1506636488490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.710833, 38.743, 2.06 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935467", "mag": 1.1, "time": 1506635722873, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.2148, 64.8337, 24.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989663", "mag": 1.2, "time": 1506634878192, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0761, 62.868, 105.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aw7x", "mag": 3.3, "time": 1506634428280, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 19.9413, 39.9063, 10.29 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989662", "mag": 1.3, "time": 1506634090975, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8044, 63.1677, 125.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b1wj", "mag": 4.0, "time": 1506633989680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 150.778, 49.1768, 363.15 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935454", "mag": 2.6, "time": 1506633516577, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9288, 61.8846, 49.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935459", "mag": 2.8, "time": 1506633516034, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7041, 61.8689, 59.8 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607410", "mag": 2.0, "time": 1506633382650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9234, 38.4032, 7.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935451", "mag": 1.7, "time": 1506632963331, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.6029, 62.2054, 19.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci38013352", "mag": 1.79, "time": 1506632691350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.990833, 33.765333, 14.42 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607723", "mag": 1.0, "time": 1506632347835, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.1182, 38.2802, 11.5 ] } }, +{ "type": "Feature", "properties": { "id": "hv61925221", "mag": 1.37, "time": 1506631999030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.430333, 19.4155, 3.336 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935443", "mag": 2.3, "time": 1506631969817, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.484, 61.7831, 31.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aw54", "mag": 2.4, "time": 1506631716330, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.3897, 35.6755, 5.86 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aw51", "mag": 4.7, "time": 1506631326570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 129.2381, -7.2814, 142.87 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989658", "mag": 1.3, "time": 1506630830832, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5815, 63.2958, 125.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935439", "mag": 1.8, "time": 1506629924653, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.1989, 60.9639, 35.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci38013336", "mag": 1.94, "time": 1506629828900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.131167, 32.218833, 17.71 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989656", "mag": 1.2, "time": 1506629660078, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0033, 63.1036, 120.6 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258194", "mag": 1.36, "time": 1506628850530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.525833, 46.870167, 10.85 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989655", "mag": 1.6, "time": 1506628609513, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2274, 59.9548, 119.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989654", "mag": 1.5, "time": 1506627145969, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.4925, 59.606, 72.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900741", "mag": 1.19, "time": 1506626419400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.631667, 36.039167, 2.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989653", "mag": 1.4, "time": 1506626367074, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.3296, 60.9023, 42.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aw2q", "mag": 4.9, "time": 1506625864960, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -84.1381, 3.222, 33.2 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249967", "mag": 1.41, "time": 1506625553170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.457167, 42.614667, 6.24 ] } }, +{ "type": "Feature", "properties": { "id": "ak16933835", "mag": 2.9, "time": 1506625397763, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -171.0327, 52.1592, 53.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci38013288", "mag": 1.11, "time": 1506625160340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.118167, 33.2435, 12.25 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989651", "mag": 1.3, "time": 1506624662212, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.6565, 62.7268, 75.5 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607390", "mag": 1.2, "time": 1506624316884, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.0954, 35.994, 9.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16933797", "mag": 2.1, "time": 1506623643983, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.596, 60.994, 73.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16933794", "mag": 1.9, "time": 1506623613173, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.8361, 62.7886, 1.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci38013264", "mag": 1.24, "time": 1506622262550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.530333, 35.347, 5.41 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989648", "mag": 1.6, "time": 1506621791811, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.5986, 59.752, 76.2 ] } }, +{ "type": "Feature", "properties": { "id": "hv61924821", "mag": 2.4, "time": 1506621499160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.122167, 19.331, 7.032 ] } }, +{ "type": "Feature", "properties": { "id": "ak16933793", "mag": 1.6, "time": 1506621344909, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.8725, 59.9048, 16.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900701", "mag": 1.21, "time": 1506621263930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.129833, 36.62, 9.54 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258169", "mag": 1.95, "time": 1506620957630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.495833, 46.896167, 10.98 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989646", "mag": 1.2, "time": 1506620810224, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.5002, 61.5482, 31.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900691", "mag": 1.44, "time": 1506620029980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.995833, 39.427167, 0.18 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989645", "mag": 1.5, "time": 1506619134173, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0379, 60.1776, 121.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci38013232", "mag": 1.17, "time": 1506618737450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.792167, 33.506833, 5.73 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avzh", "mag": 4.6, "time": 1506618485320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 127.5691, 2.1483, 97.53 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avzb", "mag": 4.9, "time": 1506617586500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 120.0401, 6.0164, 50.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16933018", "mag": 1.2, "time": 1506617374262, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7645, 61.7278, 64.1 ] } }, +{ "type": "Feature", "properties": { "id": "hv61924676", "mag": 1.37, "time": 1506617124930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.142167, 19.3215, 5.152 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989643", "mag": 1.6, "time": 1506616564611, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.8062, 60.4189, 2.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989642", "mag": 1.4, "time": 1506615776447, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.9273, 61.5228, 95.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989641", "mag": 1.3, "time": 1506615666771, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.3551, 60.8947, 43.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avyw", "mag": 2.7, "time": 1506615478140, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4394, 42.5767, 8.98 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900646", "mag": 1.38, "time": 1506615468050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.0045, 36.4415, 0.06 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989640", "mag": 1.3, "time": 1506615161794, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.0408, 63.589, 132.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989639", "mag": 1.2, "time": 1506615119980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.3231, 63.0526, 91.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16933017", "mag": 2.0, "time": 1506614678900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.3488, 68.1439, 6.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989637", "mag": 2.0, "time": 1506614163379, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.1177, 57.8245, 115.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900616", "mag": 1.97, "time": 1506613917930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.833833, 37.506167, 0.46 ] } }, +{ "type": "Feature", "properties": { "id": "ak16933016", "mag": 1.5, "time": 1506613537003, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1247, 62.197, 80.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900606", "mag": 1.53, "time": 1506612805340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.996667, 39.425333, 0.77 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989634", "mag": 1.6, "time": 1506612409300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.4495, 58.785, 109.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989633", "mag": 1.3, "time": 1506612360069, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.6854, 61.515, 2.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avy5", "mag": 2.4, "time": 1506612136390, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.1391, 37.351, 10.96 ] } }, +{ "type": "Feature", "properties": { "id": "ak16932254", "mag": 1.6, "time": 1506612041072, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.9819, 62.3692, 40.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avxu", "mag": 2.3, "time": 1506611699680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.3926, 36.3885, 15.33 ] } }, +{ "type": "Feature", "properties": { "id": "ak16932252", "mag": 1.4, "time": 1506611616543, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.7975, 61.8375, 20.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900586", "mag": 1.03, "time": 1506611392120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.821335, 38.808834, 2.14 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900581", "mag": 1.68, "time": 1506611003850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.995167, 39.428167, 0.76 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900571", "mag": 3.21, "time": 1506610414710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -127.1635, 40.137833, 15.62 ] } }, +{ "type": "Feature", "properties": { "id": "ak16932251", "mag": 2.9, "time": 1506610104421, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.9091, 51.7632, 40.8 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249947", "mag": 1.1, "time": 1506608975840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.421333, 42.593667, 5.84 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900556", "mag": 1.09, "time": 1506608575910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.821333, 37.6065, 3.9 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249942", "mag": 1.52, "time": 1506608341480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.415667, 42.591167, 5.46 ] } }, +{ "type": "Feature", "properties": { "id": "ak16932247", "mag": 2.1, "time": 1506608150712, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.4995, 59.282, 98.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989627", "mag": 1.2, "time": 1506607597338, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.5495, 63.4604, 104.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989625", "mag": 1.6, "time": 1506607488149, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.3463, 61.0393, 106.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16932246", "mag": 1.4, "time": 1506606933995, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.1075, 61.1056, 49.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16932241", "mag": 2.4, "time": 1506606217414, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.3566, 59.8225, 132.2 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607373", "mag": 1.4, "time": 1506605920785, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.4887, 38.6992, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989622", "mag": 1.0, "time": 1506605668248, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.09, 62.8911, 77.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16932239", "mag": 1.5, "time": 1506605540122, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.5382, 63.0052, 72.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900531", "mag": 1.45, "time": 1506605237980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.023333, 37.519667, 2.73 ] } }, +{ "type": "Feature", "properties": { "id": "uw61334636", "mag": 1.41, "time": 1506604992060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.905, 48.235833, 11.65 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989620", "mag": 1.1, "time": 1506604766781, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.9752, 64.7557, 17.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900521", "mag": 1.23, "time": 1506604242090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.078, 37.663333, 7.74 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989619", "mag": 1.3, "time": 1506603071727, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.42, 61.0462, 108.0 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249937", "mag": 2.05, "time": 1506602964450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.440333, 42.584, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16931481", "mag": 1.0, "time": 1506601991313, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.596, 66.821, 3.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989616", "mag": 1.3, "time": 1506601744056, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.1565, 57.9069, 53.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989615", "mag": 1.2, "time": 1506601651411, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3908, 68.9058, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16931479", "mag": 1.4, "time": 1506601472327, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.4079, 61.6728, 40.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16931477", "mag": 1.1, "time": 1506601302752, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8998, 65.8646, 6.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900496", "mag": 1.36, "time": 1506601178090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.88, 37.535, 2.88 ] } }, +{ "type": "Feature", "properties": { "id": "ak16931475", "mag": 1.2, "time": 1506600842484, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.174, 61.7151, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900446", "mag": 2.75, "time": 1506598677940, "felt": 11, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.825333, 38.840167, 1.73 ] } }, +{ "type": "Feature", "properties": { "id": "ak16930710", "mag": 2.2, "time": 1506598490657, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4189, 62.1612, 87.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avvw", "mag": 5.3, "time": 1506598185690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 140.558, 28.7786, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989610", "mag": 1.2, "time": 1506597726479, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.1805, 63.0271, 90.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900431", "mag": 1.92, "time": 1506596753080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.485667, 38.5015, 5.55 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989609", "mag": 1.5, "time": 1506596722964, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.1313, 51.5863, 44.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16930709", "mag": 1.4, "time": 1506596180091, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9834, 61.0931, 56.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16930708", "mag": 3.1, "time": 1506595515294, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 176.7195, 51.6195, 25.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989606", "mag": 1.5, "time": 1506595427986, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.5238, 51.5739, 68.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900416", "mag": 1.17, "time": 1506594935360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.096, 36.553167, 9.44 ] } }, +{ "type": "Feature", "properties": { "id": "ak16930706", "mag": 1.2, "time": 1506593895889, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.338, 63.1851, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012984", "mag": 1.12, "time": 1506593315340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.6855, 35.838833, 4.14 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900391", "mag": 1.49, "time": 1506592222290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.823333, 37.607, 4.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16930705", "mag": 1.1, "time": 1506591630653, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.3689, 61.3755, 23.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012952", "mag": 1.31, "time": 1506591135600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.834333, 32.734667, 5.37 ] } }, +{ "type": "Feature", "properties": { "id": "hv61924526", "mag": 1.45, "time": 1506590418070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.421333, 19.392167, 9.534 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900381", "mag": 1.63, "time": 1506590284210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.2205, 38.063167, 9.05 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avu4", "mag": 4.4, "time": 1506589563580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -66.6261, -23.7242, 196.73 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989602", "mag": 2.7, "time": 1506589434755, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -170.4192, 52.1877, 22.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012928", "mag": 1.18, "time": 1506589107820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.7675, 33.325167, 12.65 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989601", "mag": 1.5, "time": 1506589104993, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4957, 51.6758, 15.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16929945", "mag": 2.3, "time": 1506588754779, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.7058, 62.131, 34.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16929940", "mag": 2.6, "time": 1506588542400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.6191, 66.8364, 10.5 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607351", "mag": 1.4, "time": 1506588343442, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9118, 38.3801, 6.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16929936", "mag": 2.0, "time": 1506587984225, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.4437, 61.9903, 29.6 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258129", "mag": 1.62, "time": 1506587784100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.525167, 46.868167, 10.62 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900351", "mag": 1.19, "time": 1506586386820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.880833, 37.536333, 3.07 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avte", "mag": 4.7, "time": 1506586379850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 117.1706, -10.7291, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avtg", "mag": 5.3, "time": 1506586316130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 145.2449, 20.2657, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16929174", "mag": 2.3, "time": 1506586272361, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.7694, 61.6101, 47.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900346", "mag": 1.18, "time": 1506586053100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.823, 37.610167, 4.21 ] } }, +{ "type": "Feature", "properties": { "id": "uw61334586", "mag": 2.19, "time": 1506585933680, "felt": 9, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.6315, 48.074, -0.77 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607345", "mag": 1.8, "time": 1506585602623, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.6237, 38.7874, 8.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16929171", "mag": 1.6, "time": 1506585414754, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.1681, 58.2365, 0.7 ] } }, +{ "type": "Feature", "properties": { "id": "hv61924441", "mag": 1.7, "time": 1506585350220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.865167, 19.430333, 13.243 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900326", "mag": 1.41, "time": 1506585322460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.751, 38.783, 2.58 ] } }, +{ "type": "Feature", "properties": { "id": "ak16929167", "mag": 2.4, "time": 1506585219017, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.0108, 65.3932, 8.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16929164", "mag": 1.6, "time": 1506585151006, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.7632, 61.6155, 48.1 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607342", "mag": 1.4, "time": 1506584922597, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.6325, 38.7911, 6.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16929162", "mag": 1.5, "time": 1506584839080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.6957, 59.8727, 1.2 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258114", "mag": 1.59, "time": 1506584469140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.525167, 46.867333, 10.81 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258109", "mag": 1.16, "time": 1506584073450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.53, 46.878167, 13.02 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012872", "mag": 1.17, "time": 1506583959450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.817833, 34.8665, 6.68 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989588", "mag": 1.8, "time": 1506583466047, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2642, 60.2053, 132.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awdi", "mag": 1.5, "time": 1506583342200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -69.1659, 45.241, 4.82 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avsq", "mag": 4.8, "time": 1506582689240, "felt": 6, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 141.4054, 37.4649, 44.08 ] } }, +{ "type": "Feature", "properties": { "id": "ak16928412", "mag": 1.8, "time": 1506582059678, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -159.6189, 67.5652, 16.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16928397", "mag": 2.0, "time": 1506580602424, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.1188, 61.1485, 13.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16928399", "mag": 1.1, "time": 1506580596261, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.8057, 66.0421, 6.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900281", "mag": 1.14, "time": 1506579131440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.88, 37.5365, 3.19 ] } }, +{ "type": "Feature", "properties": { "id": "ak16928394", "mag": 1.6, "time": 1506578908430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.0895, 61.7515, 17.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012840", "mag": 0.96, "time": 1506578825230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.767667, 36.025167, 1.05 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012832", "mag": 1.0, "time": 1506578679490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.884833, 33.846833, 11.18 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249902", "mag": 1.26, "time": 1506578472190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.285833, 41.514167, 1.58 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249897", "mag": 1.56, "time": 1506578161990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4205, 42.5195, 5.83 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989578", "mag": 1.2, "time": 1506577617968, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.0285, 60.9615, 99.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16927642", "mag": 2.5, "time": 1506576956542, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4519, 60.4702, 49.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16927639", "mag": 1.1, "time": 1506575989243, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.9371, 64.4345, 12.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avrg", "mag": 4.2, "time": 1506575321430, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9228, 16.6784, 58.25 ] } }, +{ "type": "Feature", "properties": { "id": "ak16927634", "mag": 1.4, "time": 1506574806948, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9601, 61.6771, 57.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avr9", "mag": 3.0, "time": 1506574593800, "felt": 16, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -96.8025, 35.9915, 5.225 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900251", "mag": 1.08, "time": 1506573201460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.876833, 37.531833, 2.55 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989573", "mag": 1.0, "time": 1506573124099, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.1846, 68.5953, 17.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900241", "mag": 2.37, "time": 1506572664450, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8255, 37.454833, 2.13 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900236", "mag": 1.11, "time": 1506572038110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.088333, 36.5915, 6.51 ] } }, +{ "type": "Feature", "properties": { "id": "ak16927631", "mag": 2.2, "time": 1506572029624, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 178.6248, 51.535, 13.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989570", "mag": 1.3, "time": 1506571605724, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.1124, 61.418, 10.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avr1", "mag": 2.8, "time": 1506571358890, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.1712, 37.3741, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avqw", "mag": 3.2, "time": 1506571014630, "felt": 6, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.1535, 37.3739, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avr2", "mag": 4.9, "time": 1506570988200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 151.8102, -5.2471, 64.55 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900206", "mag": 1.12, "time": 1506569953990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.878833, 37.5315, 2.34 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900201", "mag": 1.78, "time": 1506569868050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.191167, 36.174833, 16.31 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258089", "mag": 0.96, "time": 1506568483250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5215, 46.872833, 14.45 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900166", "mag": 1.94, "time": 1506568350160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.970833, 36.399167, 0.33 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900156", "mag": 1.95, "time": 1506567041430, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8805, 37.535167, 2.92 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607321", "mag": 1.0, "time": 1506566989487, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.0173, 39.5809, 8.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012696", "mag": 1.54, "time": 1506566359150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.3855, 33.309667, 7.18 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926883", "mag": 1.4, "time": 1506564828219, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7449, 64.3314, 9.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926881", "mag": 1.6, "time": 1506563449576, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.7299, 60.5992, 21.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avqf", "mag": 3.5, "time": 1506563003590, "felt": 11, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -1.5206, 47.8948, 7.47 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avq4", "mag": 3.4, "time": 1506562916490, "felt": 8, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -83.8862, 9.972, 12.77 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926876", "mag": 1.5, "time": 1506562750811, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2038, 62.3276, 80.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989563", "mag": 2.4, "time": 1506562282380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.5433, 52.3165, 175.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012648", "mag": 1.44, "time": 1506561221540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.9255, 33.975833, 5.98 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989561", "mag": 1.2, "time": 1506560682030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.3529, 60.5442, 7.3 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249877", "mag": 2.9, "time": 1506560508370, "felt": 9, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.946, 38.905, 8.36 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012624", "mag": 1.0, "time": 1506559691050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.812, 36.016833, 1.28 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012616", "mag": 1.66, "time": 1506559333880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.939667, 33.686667, 9.17 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926874", "mag": 1.3, "time": 1506559196699, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5701, 61.4562, 64.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900121", "mag": 1.32, "time": 1506558055260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.2635, 39.396667, 0.45 ] } }, +{ "type": "Feature", "properties": { "id": "ak16989559", "mag": 1.0, "time": 1506557933118, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.9128, 61.7015, 46.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012608", "mag": 1.47, "time": 1506557437030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.089667, 35.6985, 2.41 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900106", "mag": 1.15, "time": 1506556889810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.794, 38.821167, 2.63 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607313", "mag": 1.3, "time": 1506556883650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.1041, 37.378, 3.6 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258084", "mag": 1.57, "time": 1506556538250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.526333, 46.874833, 14.66 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607310", "mag": 1.6, "time": 1506556172753, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.059, 37.1112, 7.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926873", "mag": 1.3, "time": 1506556116361, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.4042, 53.8015, 12.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900096", "mag": 1.12, "time": 1506556022400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.731667, 38.760166, 1.18 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988195", "mag": 1.9, "time": 1506555035171, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0633, 60.0089, 114.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avn9", "mag": 4.2, "time": 1506555004800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 119.4365, -8.2451, 154.02 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900086", "mag": 1.16, "time": 1506554882180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.738335, 38.755333, 0.36 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926134", "mag": 1.1, "time": 1506554881350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.2845, 60.8545, 21.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988193", "mag": 1.0, "time": 1506554670593, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.1097, 62.4437, 13.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926036", "mag": 1.3, "time": 1506554241873, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.6125, 61.555, 35.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900081", "mag": 1.22, "time": 1506554024900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.832, 37.5385, 4.78 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012576", "mag": 1.27, "time": 1506553539380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.392833, 34.878667, 4.66 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926028", "mag": 1.6, "time": 1506553116940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -159.5885, 67.5732, 17.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012568", "mag": 1.61, "time": 1506552976740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.758833, 33.666667, 13.28 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926026", "mag": 1.6, "time": 1506552344260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.6143, 63.0496, 5.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988188", "mag": 1.0, "time": 1506552342400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.0102, 64.7419, 2.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926025", "mag": 1.7, "time": 1506551886678, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4287, 51.666, 13.3 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249842", "mag": 1.14, "time": 1506551770950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.297667, 41.517833, 3.93 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926021", "mag": 1.0, "time": 1506550963839, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.7318, 63.2463, 16.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012528", "mag": 1.36, "time": 1506549674520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.792167, 33.505667, 5.04 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avlw", "mag": 4.5, "time": 1506549399140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 123.4716, 24.998, 125.83 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988184", "mag": 1.9, "time": 1506549387020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.4366, 51.4823, 54.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900041", "mag": 1.15, "time": 1506549261590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.745331, 38.788502, 0.88 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249832", "mag": 1.22, "time": 1506548944800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.294333, 41.516333, 2.01 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avm6", "mag": 4.7, "time": 1506548861390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 140.5824, 28.7476, 33.11 ] } }, +{ "type": "Feature", "properties": { "id": "hv61923721", "mag": 1.68, "time": 1506548248460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.233167, 19.411667, 26.335 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988183", "mag": 1.1, "time": 1506547027410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5065, 62.8856, 85.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988182", "mag": 1.3, "time": 1506546817449, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3499, 60.4052, 65.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avkb", "mag": 4.8, "time": 1506546638200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 140.5529, 28.769, 38.59 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avk0", "mag": 4.4, "time": 1506545901120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -73.9242, -10.8691, 104.23 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900011", "mag": 1.24, "time": 1506545494440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7435, 38.775167, 0.33 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258059", "mag": 1.99, "time": 1506545099310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.533833, 46.865333, 12.52 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988181", "mag": 1.9, "time": 1506544970602, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.5993, 58.8739, 125.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc71107599", "mag": 1.73, "time": 1506544649060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.852333, 36.770333, 5.22 ] } }, +{ "type": "Feature", "properties": { "id": "nc72900001", "mag": 1.02, "time": 1506544641500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.307333, 35.890833, 9.61 ] } }, +{ "type": "Feature", "properties": { "id": "uw61334351", "mag": 1.62, "time": 1506543856900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.103667, 46.818167, -0.37 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avim", "mag": 4.5, "time": 1506542712990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -71.6095, -15.1614, 131.74 ] } }, +{ "type": "Feature", "properties": { "id": "ak16924547", "mag": 1.3, "time": 1506542654107, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.6538, 61.2784, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899976", "mag": 1.46, "time": 1506542639270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.024, 37.520333, 2.59 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988179", "mag": 1.4, "time": 1506542327610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.9637, 61.5729, 96.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988178", "mag": 1.2, "time": 1506541938004, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1366, 60.2787, 53.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16924544", "mag": 1.5, "time": 1506541523210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.1298, 59.8511, 15.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16924540", "mag": 3.0, "time": 1506540667871, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -179.8525, 51.0507, 13.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16924539", "mag": 1.3, "time": 1506540652841, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -138.178, 61.5488, 2.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012400", "mag": 0.98, "time": 1506540581720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.481833, 33.471167, 13.16 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988174", "mag": 1.1, "time": 1506540333948, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.501, 61.2429, 47.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012384", "mag": 1.3, "time": 1506539422810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.197, 34.992, -0.84 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258049", "mag": 1.59, "time": 1506539240620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.472833, 46.002167, -2.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899931", "mag": 1.55, "time": 1506538588360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.4435, 38.569833, 7.29 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012368", "mag": 1.32, "time": 1506538425860, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.193167, 34.018167, 9.75 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012360", "mag": 1.78, "time": 1506537986730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.929, 33.395, 16.07 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258044", "mag": 1.34, "time": 1506537974910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.524833, 46.870667, 11.9 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258039", "mag": 1.67, "time": 1506537644220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.525, 46.873167, 11.84 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012352", "mag": 1.26, "time": 1506537396500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.313333, 35.0755, -0.97 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988173", "mag": 2.5, "time": 1506536259670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2174, 55.267, 28.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16923724", "mag": 1.8, "time": 1506535852212, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.5095, 57.4219, 64.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012280", "mag": 1.04, "time": 1506535593850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.8595, 37.1805, -1.52 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258024", "mag": 1.14, "time": 1506535428310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.542833, 46.867, 15.39 ] } }, +{ "type": "Feature", "properties": { "id": "ak16923723", "mag": 1.8, "time": 1506535251777, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.8081, 59.8933, 18.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899896", "mag": 1.43, "time": 1506534720980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.1055, 37.325167, -0.31 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607242", "mag": 1.3, "time": 1506533616061, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.8105, 37.3086, 1.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16922991", "mag": 1.3, "time": 1506533488405, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0074, 62.0045, 73.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16922987", "mag": 1.8, "time": 1506533174170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.1276, 62.1421, 107.7 ] } }, +{ "type": "Feature", "properties": { "id": "mb80258019", "mag": 1.36, "time": 1506533071220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.9895, 46.553167, -2.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012256", "mag": 1.4, "time": 1506532727840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.796333, 33.501667, 4.58 ] } }, +{ "type": "Feature", "properties": { "id": "ak16922978", "mag": 3.9, "time": 1506532451736, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.5261, 52.9317, 19.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16922973", "mag": 1.3, "time": 1506532279574, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.0546, 62.1579, 12.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16922968", "mag": 2.2, "time": 1506532267245, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0431, 59.4743, 92.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16922975", "mag": 1.9, "time": 1506532266486, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.1368, 59.6598, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16922963", "mag": 1.1, "time": 1506530768012, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.1018, 64.1209, 3.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16924550", "mag": 2.4, "time": 1506530256430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.6494, 52.9731, 12.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avec", "mag": 2.6, "time": 1506529974600, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.0737, 44.3257, 12.14 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899871", "mag": 1.08, "time": 1506529473980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.836, 37.569167, 1.23 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012176", "mag": 1.03, "time": 1506529247980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.795833, 33.502, 4.86 ] } }, +{ "type": "Feature", "properties": { "id": "ak16922238", "mag": 1.6, "time": 1506529055903, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.7065, 67.422, 11.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899866", "mag": 1.85, "time": 1506528932600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.995833, 39.432667, 3.11 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ave0", "mag": 4.1, "time": 1506528488760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 119.9926, -7.5373, 611.74 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avdr", "mag": 4.1, "time": 1506527126210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 129.0234, -7.2935, 121.06 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899831", "mag": 1.23, "time": 1506526130580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.231667, 35.611, 3.55 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988160", "mag": 1.6, "time": 1506525379416, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.9254, 58.9648, 66.9 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257999", "mag": 1.8, "time": 1506524825390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.533333, 46.866, 13.41 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899816", "mag": 1.11, "time": 1506524218360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.989167, 37.558167, 1.34 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988159", "mag": 1.2, "time": 1506524092965, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.7404, 58.8609, 4.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012112", "mag": 1.73, "time": 1506523530510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.417833, 34.440833, 0.65 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899796", "mag": 0.95, "time": 1506523499180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8715, 37.492667, 3.48 ] } }, +{ "type": "Feature", "properties": { "id": "ak16921504", "mag": 1.8, "time": 1506522635679, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3466, 59.8103, 47.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988157", "mag": 1.5, "time": 1506522267480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.561, 57.6875, 76.6 ] } }, +{ "type": "Feature", "properties": { "id": "uw61311512", "mag": 1.06, "time": 1506522173600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.941333, 47.1825, 15.72 ] } }, +{ "type": "Feature", "properties": { "id": "ak16920785", "mag": 2.4, "time": 1506522058371, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.3316, 56.7652, 41.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16920784", "mag": 1.4, "time": 1506521703637, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.533, 60.0761, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "hv61923421", "mag": 1.78, "time": 1506521436470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.401167, 19.199167, 32.961 ] } }, +{ "type": "Feature", "properties": { "id": "ak16920775", "mag": 2.0, "time": 1506520826084, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.649, 61.9693, 57.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16920772", "mag": 2.0, "time": 1506520439615, "felt": 0, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.2196, 59.6108, 85.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16920758", "mag": 2.9, "time": 1506520230887, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.3755, 61.9643, 42.4 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257989", "mag": 1.28, "time": 1506520220400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5215, 46.870167, 11.81 ] } }, +{ "type": "Feature", "properties": { "id": "ak16920757", "mag": 1.0, "time": 1506520046138, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.5503, 65.1678, 11.6 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607209", "mag": 1.5, "time": 1506519994705, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.7233, 40.1708, 10.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci38012040", "mag": 1.13, "time": 1506519953180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.935333, 34.4565, 9.26 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899776", "mag": 1.01, "time": 1506519567480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.840667, 37.5315, -1.51 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899766", "mag": 1.77, "time": 1506519075660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.243667, 39.398333, 12.87 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899761", "mag": 1.35, "time": 1506518981970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.745833, 38.784333, 1.01 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avce", "mag": 2.7, "time": 1506518011840, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.555, 46.8463, 8.48 ] } }, +{ "type": "Feature", "properties": { "id": "ak16920754", "mag": 2.5, "time": 1506517941863, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 179.4288, 51.3519, 42.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16920753", "mag": 1.2, "time": 1506517783977, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.1318, 60.4494, 8.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16920743", "mag": 2.6, "time": 1506516302533, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.0235, 61.6238, 41.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988145", "mag": 1.2, "time": 1506515748862, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9213, 61.1389, 61.5 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257979", "mag": 1.95, "time": 1506514222430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.528667, 46.869667, 13.01 ] } }, +{ "type": "Feature", "properties": { "id": "ak16920741", "mag": 1.4, "time": 1506513863630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.4582, 62.4107, 39.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16920740", "mag": 2.1, "time": 1506513265227, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -168.2773, 65.177, 2.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16920737", "mag": 1.4, "time": 1506513028050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.1779, 58.0206, 30.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16920020", "mag": 1.9, "time": 1506512934355, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -135.4027, 59.1963, 7.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16920019", "mag": 1.3, "time": 1506511124207, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.9174, 59.9564, 76.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011952", "mag": 1.07, "time": 1506511069520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.789667, 33.489167, 5.35 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257974", "mag": 1.33, "time": 1506510967360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.526833, 46.881, 13.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avaw", "mag": 2.7, "time": 1506509852090, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -103.2764, 31.1697, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899726", "mag": 1.29, "time": 1506508915160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.809, 38.828833, 0.37 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899721", "mag": 1.52, "time": 1506508865060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.074167, 36.490333, 6.54 ] } }, +{ "type": "Feature", "properties": { "id": "ak16920017", "mag": 1.5, "time": 1506508671618, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.664, 59.7325, 12.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899716", "mag": 1.33, "time": 1506507368050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.621833, 36.9715, 5.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988138", "mag": 1.5, "time": 1506506488102, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.3194, 60.198, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899711", "mag": 1.1, "time": 1506506346060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.830667, 37.480333, -1.14 ] } }, +{ "type": "Feature", "properties": { "id": "ak16920009", "mag": 1.7, "time": 1506506054796, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.8154, 59.9932, 104.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988136", "mag": 1.4, "time": 1506505999692, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.1528, 59.8387, 71.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16920005", "mag": 1.7, "time": 1506505194635, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.0126, 61.1428, 12.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16920003", "mag": 1.3, "time": 1506504555844, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.6373, 60.4592, 9.8 ] } }, +{ "type": "Feature", "properties": { "id": "hv61923186", "mag": 1.49, "time": 1506503971290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.2035, 19.597167, 24.581 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607200", "mag": 1.3, "time": 1506503935311, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.2622, 38.0846, 9.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000av9q", "mag": 3.0, "time": 1506503712310, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -103.2693, 31.1511, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899701", "mag": 1.06, "time": 1506503394340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.819167, 37.604333, 4.32 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257964", "mag": 1.06, "time": 1506503136100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.529667, 46.8705, 10.5 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249807", "mag": 1.65, "time": 1506503101030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.067, 42.665833, 6.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011904", "mag": 1.21, "time": 1506502961890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.0485, 33.171333, 5.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000av9i", "mag": 4.2, "time": 1506502867800, "felt": 8, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -71.3374, -29.45, 38.77 ] } }, +{ "type": "Feature", "properties": { "id": "ak16919291", "mag": 2.0, "time": 1506502630723, "felt": 6, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -135.4344, 59.1851, 6.2 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249797", "mag": 1.72, "time": 1506502497570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.061667, 42.664667, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011896", "mag": 1.37, "time": 1506502201400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.052, 33.172, 6.03 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011880", "mag": 1.16, "time": 1506501606110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.542667, 32.944667, 6.67 ] } }, +{ "type": "Feature", "properties": { "id": "us2000av94", "mag": 4.6, "time": 1506500888720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 54.1871, 28.1091, 45.31 ] } }, +{ "type": "Feature", "properties": { "id": "ak16919288", "mag": 1.0, "time": 1506500817789, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.4269, 65.2147, 15.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988130", "mag": 2.0, "time": 1506500078029, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 179.5053, 51.0555, 12.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc71107564", "mag": 1.29, "time": 1506499044330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.570833, 38.927167, 9.62 ] } }, +{ "type": "Feature", "properties": { "id": "us2000av8z", "mag": 4.3, "time": 1506498944880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -179.1801, -21.2747, 610.22 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899666", "mag": 1.1, "time": 1506498551180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8395, 37.568167, 1.44 ] } }, +{ "type": "Feature", "properties": { "id": "ak16918579", "mag": 1.9, "time": 1506498372082, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.5535, 59.8103, 129.5 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70235883", "mag": 1.79, "time": 1506498339870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.776167, 37.332333, 4.84 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899656", "mag": 1.07, "time": 1506497879900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.818169, 38.816334, 2.44 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988128", "mag": 1.7, "time": 1506497626569, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.5074, 58.9707, 125.1 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607194", "mag": 1.4, "time": 1506496907372, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.0035, 38.4922, 2.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16918577", "mag": 2.4, "time": 1506495198173, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -175.3064, 51.5599, 38.1 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607192", "mag": 1.3, "time": 1506495045147, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.1202, 38.2811, 9.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16917880", "mag": 1.4, "time": 1506494125518, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.4062, 59.5783, 46.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011824", "mag": 2.15, "time": 1506493452570, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.377, 34.425667, 6.94 ] } }, +{ "type": "Feature", "properties": { "id": "ak16917877", "mag": 1.0, "time": 1506493181446, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.74, 66.8722, 13.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988124", "mag": 2.0, "time": 1506492309885, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -179.6222, 51.5723, 70.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16917874", "mag": 1.0, "time": 1506491782705, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.3009, 62.1686, 20.4 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70235878", "mag": 1.72, "time": 1506491740260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.966167, 37.277667, 3.84 ] } }, +{ "type": "Feature", "properties": { "id": "ak16917871", "mag": 2.2, "time": 1506491690990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.227, 67.4203, 2.2 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257949", "mag": 1.15, "time": 1506491507770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.53, 46.8695, 10.41 ] } }, +{ "type": "Feature", "properties": { "id": "ak16917866", "mag": 2.4, "time": 1506491501818, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.2772, 62.1792, 19.3 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70235873", "mag": 2.14, "time": 1506491075330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.886, 37.201833, 5.78 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257939", "mag": 1.58, "time": 1506490489800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.536833, 46.867667, 13.76 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607189", "mag": 1.5, "time": 1506490367737, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.114, 38.2859, 6.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011800", "mag": 2.36, "time": 1506490230430, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.3735, 34.4205, 2.68 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011808", "mag": 1.19, "time": 1506490229680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.296833, 33.257333, 11.15 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899631", "mag": 1.3, "time": 1506489660140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.492333, 37.643167, 10.59 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011776", "mag": 1.48, "time": 1506489097510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.050333, 33.1715, 3.79 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011760", "mag": 1.09, "time": 1506488442000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.1045, 34.032667, 6.24 ] } }, +{ "type": "Feature", "properties": { "id": "ak16917162", "mag": 1.2, "time": 1506488287570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.7916, 59.8749, 12.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16917160", "mag": 1.7, "time": 1506488119627, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.8594, 59.8596, 52.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011736", "mag": 1.35, "time": 1506488015210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.011667, 33.275333, 2.98 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011728", "mag": 1.28, "time": 1506487875520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.796667, 33.492, 4.46 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011720", "mag": 2.62, "time": 1506487715700, "felt": 25, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.372333, 34.4215, 3.6 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249762", "mag": 1.11, "time": 1506487228770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.7735, 44.765667, 7.75 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899586", "mag": 2.03, "time": 1506485795570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.784333, 38.836667, 1.36 ] } }, +{ "type": "Feature", "properties": { "id": "us2000av7z", "mag": 5.3, "time": 1506485581610, "felt": 2, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 139.7504, -3.5926, 60.39 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607179", "mag": 1.2, "time": 1506485505469, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.6245, 38.788, 6.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000av80", "mag": 5.0, "time": 1506485392430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -43.5388, 28.7234, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000av7x", "mag": 2.7, "time": 1506485373140, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -103.2078, 31.1233, 1.49 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899571", "mag": 1.02, "time": 1506485084470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.004333, 37.796167, 1.79 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988118", "mag": 1.8, "time": 1506483937222, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.399, 51.7067, 17.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16916451", "mag": 1.9, "time": 1506483073029, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0454, 59.6347, 103.9 ] } }, +{ "type": "Feature", "properties": { "id": "uw61311302", "mag": 2.23, "time": 1506482912030, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.555, 44.547167, 12.72 ] } }, +{ "type": "Feature", "properties": { "id": "uw61311297", "mag": 1.11, "time": 1506482481740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.683, 45.372667, -1.63 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011704", "mag": 1.57, "time": 1506482455900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.519833, 32.888, 10.14 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988116", "mag": 2.0, "time": 1506482397355, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.3801, 51.6434, 13.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899551", "mag": 1.76, "time": 1506481720510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.880667, 38.659333, 5.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16915757", "mag": 1.4, "time": 1506480400030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.6852, 64.9151, 3.6 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607173", "mag": 1.2, "time": 1506479979561, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.4858, 38.7006, 5.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000av7a", "mag": 2.7, "time": 1506479406560, "felt": 8, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.8806, 37.2184, 2.69 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988114", "mag": 1.6, "time": 1506479371570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 179.3827, 51.4303, 27.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011664", "mag": 1.8, "time": 1506478585030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.628167, 35.076167, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16915754", "mag": 2.0, "time": 1506478364486, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.3878, 61.6649, 31.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16915750", "mag": 1.2, "time": 1506477958824, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.6683, 62.8518, 73.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16915745", "mag": 1.8, "time": 1506477442438, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.6565, 53.4796, 20.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000av70", "mag": 4.7, "time": 1506476740040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -68.4332, -21.409, 120.07 ] } }, +{ "type": "Feature", "properties": { "id": "ak16915060", "mag": 1.3, "time": 1506476367132, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7491, 63.2266, 126.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000av6x", "mag": 4.7, "time": 1506475551840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 126.6287, 4.6053, 83.93 ] } }, +{ "type": "Feature", "properties": { "id": "ak16915057", "mag": 2.4, "time": 1506475504238, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.2738, 57.0675, 69.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011648", "mag": 2.25, "time": 1506474971480, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.7765, 33.325667, 11.63 ] } }, +{ "type": "Feature", "properties": { "id": "nm60207341", "mag": 1.82, "time": 1506473928680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -89.549667, 36.4815, 9.25 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988107", "mag": 1.9, "time": 1506471772798, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4471, 51.7337, 16.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988106", "mag": 1.6, "time": 1506471697831, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.0762, 58.2594, 21.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b1dn", "mag": 4.3, "time": 1506471581400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 142.4161, 40.39, 49.52 ] } }, +{ "type": "Feature", "properties": { "id": "ak16915048", "mag": 1.6, "time": 1506471507429, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7558, 60.1282, 31.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16914368", "mag": 1.9, "time": 1506469962223, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.0546, 60.9937, 12.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000av6e", "mag": 4.8, "time": 1506469452030, "felt": 11, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 145.0971, 14.1324, 113.77 ] } }, +{ "type": "Feature", "properties": { "id": "ak16914364", "mag": 1.0, "time": 1506469276260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.0231, 64.8914, 16.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011608", "mag": 1.21, "time": 1506468838030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.792667, 33.506, 6.88 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949369", "mag": 1.0, "time": 1506468623879, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.2412, 61.8508, 14.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899501", "mag": 0.98, "time": 1506468157640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.873833, 37.624833, 2.99 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011600", "mag": 1.67, "time": 1506468079690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.679333, 35.033667, -0.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b02y", "mag": 4.2, "time": 1506467949880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2432, 15.0466, 41.01 ] } }, +{ "type": "Feature", "properties": { "id": "ak16914361", "mag": 1.9, "time": 1506467622189, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.6178, 65.1477, 10.9 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257914", "mag": 1.23, "time": 1506467597640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.632, 46.8715, 5.29 ] } }, +{ "type": "Feature", "properties": { "id": "ak16914358", "mag": 1.0, "time": 1506466926514, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3996, 64.9811, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16914359", "mag": 1.0, "time": 1506466913331, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.0673, 63.4886, 10.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899481", "mag": 1.12, "time": 1506466887280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.808502, 38.832001, 1.23 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949365", "mag": 1.7, "time": 1506466403289, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.9009, 59.9001, 97.4 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607152", "mag": 1.1, "time": 1506466364846, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.6252, 38.7877, 5.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000av5w", "mag": 4.8, "time": 1506465046570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -11.6494, -2.0113, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "uw61311237", "mag": 2.77, "time": 1506464518680, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.953167, 44.251833, 24.14 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011536", "mag": 1.75, "time": 1506464439110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.304167, 33.253667, 10.84 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011520", "mag": 1.59, "time": 1506463692350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.216, 33.010333, 6.85 ] } }, +{ "type": "Feature", "properties": { "id": "us2000av56", "mag": 4.2, "time": 1506463598300, "felt": 37, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -72.2376, -31.7843, 7.09 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607136", "mag": 2.8, "time": 1506462799119, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.6217, 38.7826, 6.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011488", "mag": 1.81, "time": 1506462726380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.750667, 33.516333, 3.18 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899441", "mag": 2.97, "time": 1506462683270, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -127.0155, 40.263833, 11.96 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949362", "mag": 1.6, "time": 1506462418457, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0128, 59.6612, 95.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949359", "mag": 1.6, "time": 1506461654966, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.3493, 59.8886, 123.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000av40", "mag": 5.4, "time": 1506461346270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -179.9476, -23.5856, 538.01 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899416", "mag": 1.3, "time": 1506461324290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.810333, 38.8215, 0.97 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257904", "mag": 0.95, "time": 1506461125950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.496, 46.8605, 16.29 ] } }, +{ "type": "Feature", "properties": { "id": "ak16913020", "mag": 1.1, "time": 1506460729533, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0111, 65.8632, 12.1 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257894", "mag": 1.08, "time": 1506460594630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.515167, 43.545833, 12.83 ] } }, +{ "type": "Feature", "properties": { "id": "ak16913017", "mag": 1.8, "time": 1506459899986, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.56, 59.8031, 16.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16913011", "mag": 1.9, "time": 1506459063460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.6788, 61.3357, 16.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899391", "mag": 1.35, "time": 1506458512440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.735333, 38.789833, 1.23 ] } }, +{ "type": "Feature", "properties": { "id": "hv61922451", "mag": 1.7, "time": 1506458350950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.471167, 19.227667, 34.865 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899386", "mag": 1.89, "time": 1506458341570, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.609667, 36.888333, 1.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000av31", "mag": 5.8, "time": 1506457331560, "felt": 45, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 142.4059, 40.3206, 36.04 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949355", "mag": 1.3, "time": 1506457099270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1826, 62.1538, 80.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000av2y", "mag": 2.6, "time": 1506456843780, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.9668, 37.2773, 4.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16912327", "mag": 2.1, "time": 1506456421978, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.8619, 59.5574, 79.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16912325", "mag": 1.6, "time": 1506456406002, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.0714, 61.2493, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16912323", "mag": 1.4, "time": 1506455786083, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6417, 63.0711, 110.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899366", "mag": 1.19, "time": 1506455697960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.989167, 35.677333, -0.35 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257869", "mag": 1.78, "time": 1506455523560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.4975, 46.900667, 11.16 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899361", "mag": 1.14, "time": 1506455417130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.6625, 36.100833, 0.94 ] } }, +{ "type": "Feature", "properties": { "id": "uw61311182", "mag": 1.51, "time": 1506454723910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.398833, 46.488167, 17.99 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011384", "mag": 1.37, "time": 1506454231340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.897333, 32.7725, -0.37 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257864", "mag": 1.46, "time": 1506454190410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.413167, 45.912833, -2.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011376", "mag": 1.05, "time": 1506454146060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.797167, 33.509, 6.71 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607108", "mag": 1.0, "time": 1506454067433, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.4885, 38.5144, 10.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16912305", "mag": 1.2, "time": 1506453243306, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.4352, 61.6115, 33.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000av22", "mag": 5.4, "time": 1506452898220, "felt": null, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 132.7412, 1.2169, 17.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899341", "mag": 0.98, "time": 1506452133100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.783165, 38.837833, 0.59 ] } }, +{ "type": "Feature", "properties": { "id": "us2000av1t", "mag": 4.3, "time": 1506452028320, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.6352, 16.5993, 104.33 ] } }, +{ "type": "Feature", "properties": { "id": "ak16911656", "mag": 1.1, "time": 1506451444842, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9798, 65.8633, 10.8 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257849", "mag": 1.17, "time": 1506451369960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.531667, 46.869333, 10.26 ] } }, +{ "type": "Feature", "properties": { "id": "ak16911652", "mag": 1.7, "time": 1506451256386, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.2303, 62.9438, 64.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899331", "mag": 1.39, "time": 1506451169180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.46, 37.983333, -0.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949348", "mag": 1.2, "time": 1506450622498, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9789, 62.4498, 80.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899311", "mag": 1.66, "time": 1506450429900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.811, 38.812, 2.48 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011328", "mag": 1.82, "time": 1506450379870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.7965, 33.5035, 6.49 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011320", "mag": 1.66, "time": 1506450370460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.948, 35.292167, 17.31 ] } }, +{ "type": "Feature", "properties": { "id": "hv61922336", "mag": 3.25, "time": 1506450097970, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.231, 19.290833, 8.96 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949347", "mag": 1.4, "time": 1506449901001, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.1914, 59.4295, 70.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011304", "mag": 1.2, "time": 1506449584430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.813667, 36.025833, 1.31 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011296", "mag": 0.98, "time": 1506449444340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.8115, 36.028167, 0.41 ] } }, +{ "type": "Feature", "properties": { "id": "ak16911638", "mag": 2.2, "time": 1506449441975, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.1385, 62.9479, 63.9 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257844", "mag": 1.11, "time": 1506448956940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.532, 46.8605, 12.58 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949345", "mag": 1.5, "time": 1506448347584, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.8207, 61.1514, 89.2 ] } }, +{ "type": "Feature", "properties": { "id": "uw61311142", "mag": 1.41, "time": 1506448094510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.884, 43.419667, -0.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899291", "mag": 1.2, "time": 1506447644460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.291667, 36.660333, 3.36 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949344", "mag": 2.0, "time": 1506446368069, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -161.7955, 55.6327, 123.4 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257839", "mag": 1.6, "time": 1506446229250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.530333, 46.872167, 11.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949343", "mag": 1.8, "time": 1506445879278, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.0092, 56.5802, 60.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16910871", "mag": 2.2, "time": 1506445763160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.3757, 60.912, 119.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16910870", "mag": 1.2, "time": 1506445355025, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.837, 62.5503, 9.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949340", "mag": 1.4, "time": 1506445236601, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.4629, 59.6817, 72.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16910864", "mag": 1.6, "time": 1506444383456, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.3694, 61.142, 20.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16910865", "mag": 1.1, "time": 1506444338515, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.0798, 62.3953, 8.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16910858", "mag": 2.0, "time": 1506443746387, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.5248, 63.5317, 72.7 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249707", "mag": 1.38, "time": 1506443129640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.442, 42.558833, 7.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011192", "mag": 1.03, "time": 1506442702510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.823833, 33.4855, 7.53 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899266", "mag": 1.49, "time": 1506442696750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.809833, 37.472833, 3.95 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257829", "mag": 1.46, "time": 1506441830940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.498, 46.901167, 10.66 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903841", "mag": 1.48, "time": 1506440751200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.182167, 40.8515, 3.06 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249692", "mag": 1.82, "time": 1506439249930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.139833, 42.7365, 4.13 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011112", "mag": 2.13, "time": 1506439108770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.289833, 33.302833, 10.93 ] } }, +{ "type": "Feature", "properties": { "id": "us2000auyd", "mag": 2.6, "time": 1506439089180, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4364, 42.61, 9.35 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899236", "mag": 2.73, "time": 1506439073310, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.821, 37.6035, 4.3 ] } }, +{ "type": "Feature", "properties": { "id": "hv61922126", "mag": 1.89, "time": 1506438530250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.504837, 19.188499, 37.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16910217", "mag": 1.3, "time": 1506438468368, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.3857, 61.4705, 26.0 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249677", "mag": 1.01, "time": 1506437975140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.090667, 41.940333, 4.24 ] } }, +{ "type": "Feature", "properties": { "id": "ak16909586", "mag": 1.8, "time": 1506436541694, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.9329, 61.1528, 1.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16909585", "mag": 1.5, "time": 1506436508165, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -138.6533, 59.6178, 1.5 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249672", "mag": 1.15, "time": 1506436401660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.9865, 44.768833, 6.31 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949332", "mag": 2.7, "time": 1506436259231, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 177.8212, 50.3055, 25.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949331", "mag": 1.5, "time": 1506435973793, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.5906, 57.0801, 1.8 ] } }, +{ "type": "Feature", "properties": { "id": "hv61922056", "mag": 1.6, "time": 1506435671030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.617667, 19.403833, 11.352 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899211", "mag": 1.32, "time": 1506435393920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.617833, 36.045, 5.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949330", "mag": 2.3, "time": 1506435252977, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.7207, 53.0759, 5.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000auxj", "mag": 4.2, "time": 1506434841590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -71.3743, -28.3432, 19.86 ] } }, +{ "type": "Feature", "properties": { "id": "ak16909580", "mag": 1.0, "time": 1506433271780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.9281, 62.7345, 65.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011056", "mag": 2.34, "time": 1506433147890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.097167, 32.109167, 21.13 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011048", "mag": 1.64, "time": 1506433002700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.275333, 33.9755, 2.98 ] } }, +{ "type": "Feature", "properties": { "id": "ak16909574", "mag": 2.4, "time": 1506432197049, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.1982, 63.4664, 63.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899196", "mag": 2.34, "time": 1506431642070, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.2285, 36.1555, 11.25 ] } }, +{ "type": "Feature", "properties": { "id": "ci38011032", "mag": 1.31, "time": 1506431195640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.599833, 33.196, 3.24 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949325", "mag": 1.3, "time": 1506430179945, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.5507, 57.5978, 9.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16908944", "mag": 1.5, "time": 1506430094548, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7286, 62.9807, 109.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949323", "mag": 1.4, "time": 1506429667875, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -132.545, 57.8313, 1.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16908941", "mag": 1.9, "time": 1506428870068, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.9939, 51.4819, 42.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949321", "mag": 2.3, "time": 1506428515529, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -179.9246, 51.994, 156.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000auwv", "mag": 4.8, "time": 1506428086930, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -74.1449, -37.4108, 11.74 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949320", "mag": 1.7, "time": 1506428031233, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.8671, 57.0274, 77.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899171", "mag": 1.37, "time": 1506428015870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.786167, 37.594333, 4.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949319", "mag": 1.6, "time": 1506427960144, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0976, 58.7839, 68.4 ] } }, +{ "type": "Feature", "properties": { "id": "hv61921941", "mag": 1.75, "time": 1506427855790, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.293667, 19.364833, 29.473 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257779", "mag": 1.22, "time": 1506426612780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.524667, 46.871167, 11.47 ] } }, +{ "type": "Feature", "properties": { "id": "ak16908309", "mag": 2.6, "time": 1506426273590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0017, 63.0698, 125.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16908307", "mag": 1.4, "time": 1506425656703, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.0459, 60.021, 7.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899161", "mag": 1.33, "time": 1506425143350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.737833, 38.803333, 1.75 ] } }, +{ "type": "Feature", "properties": { "id": "us2000auwh", "mag": 4.6, "time": 1506424969320, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 168.1159, -17.1048, 50.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16908306", "mag": 1.2, "time": 1506424570466, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.412, 53.8051, 14.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16908302", "mag": 1.9, "time": 1506424147684, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.7411, 59.5065, 69.7 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249657", "mag": 1.69, "time": 1506424086980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.4815, 38.756167, 9.29 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257774", "mag": 1.11, "time": 1506422972160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.387167, 44.8185, 11.24 ] } }, +{ "type": "Feature", "properties": { "id": "ak16908296", "mag": 1.6, "time": 1506420872410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.9572, 61.1571, 5.2 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607058", "mag": 1.0, "time": 1506420232880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8963, 38.401, 10.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949310", "mag": 1.6, "time": 1506419827018, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2644, 60.0718, 129.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899136", "mag": 1.49, "time": 1506419498990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.041333, 37.633667, -1.57 ] } }, +{ "type": "Feature", "properties": { "id": "ak16908294", "mag": 1.4, "time": 1506419088568, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.8181, 63.4737, 2.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949308", "mag": 1.7, "time": 1506418915220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.9641, 60.3111, 134.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010936", "mag": 1.35, "time": 1506418490150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.104333, 34.0325, 5.61 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899131", "mag": 1.28, "time": 1506417966210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.931833, 37.595833, 0.06 ] } }, +{ "type": "Feature", "properties": { "id": "ak16908292", "mag": 1.7, "time": 1506417940616, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.8017, 59.9121, 74.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16908290", "mag": 1.7, "time": 1506417796960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.402, 60.1704, 11.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949304", "mag": 1.7, "time": 1506416080631, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.871, 57.3937, 48.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949303", "mag": 1.2, "time": 1506415360742, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6564, 63.2669, 130.1 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607053", "mag": 3.4, "time": 1506415206305, "felt": 7, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8949, 38.3653, 6.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899106", "mag": 1.38, "time": 1506414957350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.0225, 37.5205, 2.13 ] } }, +{ "type": "Feature", "properties": { "id": "us2000auvr", "mag": 4.4, "time": 1506414806850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -77.3187, -5.8706, 42.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899101", "mag": 1.35, "time": 1506414495100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.810667, 37.473333, 3.46 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0x1", "mag": 4.0, "time": 1506414428310, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 115.4547, -8.3437, 7.77 ] } }, +{ "type": "Feature", "properties": { "id": "ak16907660", "mag": 2.5, "time": 1506414139904, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.2525, 63.3098, 5.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000auvl", "mag": 4.9, "time": 1506413746400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 178.8693, -24.5502, 549.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16907657", "mag": 1.7, "time": 1506413744657, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.558, 61.3722, 73.1 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607084", "mag": 1.1, "time": 1506413686395, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8996, 38.399, 10.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ax0p", "mag": 3.0, "time": 1506413645840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -162.222, 52.6448, 36.78 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010856", "mag": 1.11, "time": 1506413205840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.4375, 33.438833, 9.57 ] } }, +{ "type": "Feature", "properties": { "id": "ak16907655", "mag": 1.3, "time": 1506412718967, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.6643, 61.4913, 19.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16907652", "mag": 1.7, "time": 1506412362070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.6643, 61.6414, 22.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16907651", "mag": 1.5, "time": 1506411582373, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.2404, 59.9305, 72.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949296", "mag": 1.3, "time": 1506411274342, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.6597, 58.8354, 4.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899096", "mag": 1.03, "time": 1506410824310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.914, 37.573833, -1.62 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899091", "mag": 1.42, "time": 1506410795100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.807833, 38.8245, 2.94 ] } }, +{ "type": "Feature", "properties": { "id": "ak16907650", "mag": 2.0, "time": 1506410193440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -135.8603, 66.702, 16.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949292", "mag": 1.6, "time": 1506409745435, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.82, 59.4363, 78.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16907646", "mag": 1.1, "time": 1506408445621, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.778, 62.2517, 10.2 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249632", "mag": 2.87, "time": 1506407470180, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.651333, 44.820667, 6.96 ] } }, +{ "type": "Feature", "properties": { "id": "ak16907641", "mag": 2.2, "time": 1506407401881, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.1721, 59.3036, 66.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949289", "mag": 1.7, "time": 1506406926287, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.737, 59.5006, 82.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010824", "mag": 1.17, "time": 1506406440560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.498833, 34.926833, 12.29 ] } }, +{ "type": "Feature", "properties": { "id": "us2000auv4", "mag": 4.9, "time": 1506404788280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 101.3356, -5.7378, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000auv3", "mag": 5.0, "time": 1506404673850, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -66.5505, -21.3378, 232.1 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257744", "mag": 1.03, "time": 1506404152920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.522667, 46.9085, 12.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000auuz", "mag": 4.6, "time": 1506404004140, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.9602, 15.0621, 55.84 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949287", "mag": 1.5, "time": 1506403834555, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.1229, 59.9191, 124.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899076", "mag": 0.97, "time": 1506403715720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.825667, 37.454833, 1.23 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899066", "mag": 0.96, "time": 1506402794840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.798332, 38.824833, 2.56 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257739", "mag": 1.14, "time": 1506402535080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5275, 46.880667, 10.59 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010800", "mag": 1.46, "time": 1506401555090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.061, 34.207167, 1.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010792", "mag": 1.16, "time": 1506401392950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.064333, 34.207333, 2.74 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607042", "mag": 1.5, "time": 1506400440104, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.0413, 37.0804, 8.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16906991", "mag": 2.7, "time": 1506400345749, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.4106, 60.9055, 24.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000autd", "mag": 6.4, "time": 1506399600760, "felt": 2, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ -176.9366, -23.7135, 98.07 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257724", "mag": 1.75, "time": 1506399115590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.525167, 46.8815, 10.93 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949284", "mag": 1.4, "time": 1506398641123, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.643, 58.8409, 11.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949283", "mag": 1.3, "time": 1506398319488, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.6304, 58.8355, 8.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16906355", "mag": 2.3, "time": 1506398227222, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.8611, 62.7984, 13.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899031", "mag": 1.73, "time": 1506396860580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.823667, 37.455333, 2.55 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899036", "mag": 1.13, "time": 1506396779490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.764167, 38.956, 1.48 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249592", "mag": 1.7, "time": 1506396582400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.943167, 39.753833, 3.39 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949281", "mag": 1.5, "time": 1506396506568, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.7269, 58.5151, 73.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16906353", "mag": 1.3, "time": 1506396340348, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2988, 62.3609, 81.6 ] } }, +{ "type": "Feature", "properties": { "id": "uw61310902", "mag": 1.38, "time": 1506395899750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.737167, 47.576333, 17.19 ] } }, +{ "type": "Feature", "properties": { "id": "ak16906350", "mag": 2.1, "time": 1506395022337, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.6717, 59.8577, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70235803", "mag": 1.67, "time": 1506394171170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.620667, 37.161167, 4.48 ] } }, +{ "type": "Feature", "properties": { "id": "nc72899026", "mag": 1.36, "time": 1506393508660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.823833, 37.4545, 2.28 ] } }, +{ "type": "Feature", "properties": { "id": "ak16906345", "mag": 1.8, "time": 1506393385073, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.5638, 59.8105, 0.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16906344", "mag": 1.2, "time": 1506393361198, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.4631, 62.5638, 3.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16906343", "mag": 1.2, "time": 1506392589335, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.2072, 61.6959, 2.7 ] } }, +{ "type": "Feature", "properties": { "id": "uw61310887", "mag": 1.1, "time": 1506392466960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.9235, 46.755833, 4.01 ] } }, +{ "type": "Feature", "properties": { "id": "ak16906342", "mag": 1.8, "time": 1506392061053, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.9619, 58.719, 83.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16906341", "mag": 1.1, "time": 1506391622110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.393, 62.6136, 80.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905725", "mag": 2.0, "time": 1506390933341, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.6474, 61.5055, 2.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aus0", "mag": 5.1, "time": 1506390162180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.2892, -18.0618, 578.88 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905719", "mag": 1.0, "time": 1506388357140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.8119, 61.2841, 12.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16949271", "mag": 1.1, "time": 1506387919524, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.616, 62.8641, 85.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avl1", "mag": 4.1, "time": 1506387869490, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -68.2679, -38.2792, 18.61 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905595", "mag": 1.0, "time": 1506387645089, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.7961, 60.4358, 8.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aur8", "mag": 3.9, "time": 1506387254290, "felt": 6, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -77.6296, -12.1347, 37.62 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905592", "mag": 1.5, "time": 1506385892986, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6406, 61.6796, 57.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905589", "mag": 1.7, "time": 1506385708409, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.0359, 62.3774, 41.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898986", "mag": 1.94, "time": 1506385192120, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.759667, 38.955667, 4.16 ] } }, +{ "type": "Feature", "properties": { "id": "nn00607067", "mag": 1.1, "time": 1506385008302, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.0721, 39.3599, 7.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0hk", "mag": 4.4, "time": 1506383865610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 130.4109, -4.9919, 96.04 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0hl", "mag": 4.5, "time": 1506383851620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 3.755, 79.5651, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905583", "mag": 2.0, "time": 1506383021414, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.7759, 59.8203, 3.6 ] } }, +{ "type": "Feature", "properties": { "id": "hv61921341", "mag": 2.37, "time": 1506382999970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.826167, 19.509167, 12.397 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898971", "mag": 1.13, "time": 1506382612420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7125, 38.7455, 1.45 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898966", "mag": 1.63, "time": 1506382205240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.579, 36.013, 4.29 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010640", "mag": 1.0, "time": 1506381899530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.792667, 33.508833, 4.84 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010624", "mag": 1.86, "time": 1506381762630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.681667, 35.033833, -0.82 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898956", "mag": 1.13, "time": 1506381482700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.320667, 37.6445, 0.55 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257694", "mag": 1.58, "time": 1506381447950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.523833, 46.872833, 11.66 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0hj", "mag": 4.3, "time": 1506380384190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 115.85, -10.6682, 39.69 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010616", "mag": 1.42, "time": 1506380222440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.0935, 33.013167, -0.56 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898946", "mag": 1.13, "time": 1506379343550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7885, 38.832167, 1.97 ] } }, +{ "type": "Feature", "properties": { "id": "ld60143416", "mag": 1.71, "time": 1506378906690, "felt": 170, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -74.513833, 40.798667, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988709", "mag": 1.6, "time": 1506378800677, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.4035, 60.0163, 139.3 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257689", "mag": 1.5, "time": 1506378570060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.528833, 46.865833, 11.47 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aunr", "mag": 2.5, "time": 1506378435420, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.154, 37.3519, 3.31 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988708", "mag": 1.0, "time": 1506378350972, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.034, 64.3489, 10.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aunh", "mag": 5.0, "time": 1506377223500, "felt": null, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 124.3318, 0.8223, 219.8 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249557", "mag": 1.72, "time": 1506377199600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.460833, 42.646667, 2.74 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0hh", "mag": 4.3, "time": 1506376802200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.4659, -19.6395, 545.66 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905558", "mag": 1.3, "time": 1506376658938, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.4807, 65.756, 6.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010544", "mag": 1.52, "time": 1506375768450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.792333, 33.492, 4.2 ] } }, +{ "type": "Feature", "properties": { "id": "uw61333756", "mag": 1.11, "time": 1506375211030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.748833, 46.851167, 1.54 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010536", "mag": 1.15, "time": 1506374622610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.200667, 33.034833, 4.46 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898906", "mag": 1.32, "time": 1506373159300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.887667, 37.572333, 1.73 ] } }, +{ "type": "Feature", "properties": { "id": "ak16904952", "mag": 1.2, "time": 1506373039217, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.2776, 63.8003, 116.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16904950", "mag": 1.1, "time": 1506372955267, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1161, 63.268, 1.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898901", "mag": 1.01, "time": 1506372828820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.791667, 37.454333, 7.33 ] } }, +{ "type": "Feature", "properties": { "id": "ak16904346", "mag": 1.5, "time": 1506372342933, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.0547, 61.007, 13.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010512", "mag": 1.25, "time": 1506372237980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.492167, 33.822333, -0.52 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010488", "mag": 3.1, "time": 1506371483300, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.220833, 32.220833, 20.46 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aulg", "mag": 5.9, "time": 1506371363480, "felt": null, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 152.7133, -6.2113, 5.98 ] } }, +{ "type": "Feature", "properties": { "id": "hv61921136", "mag": 1.72, "time": 1506370768560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.421333, 19.223333, 34.311 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257664", "mag": 1.07, "time": 1506370613150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.526, 46.868, 10.18 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aukx", "mag": 2.6, "time": 1506370456500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -99.1495, 36.4119, 5.948 ] } }, +{ "type": "Feature", "properties": { "id": "us2000auky", "mag": 4.2, "time": 1506370103510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 107.7299, -5.8793, 306.63 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257659", "mag": 1.44, "time": 1506369980640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.530333, 46.8795, 12.77 ] } }, +{ "type": "Feature", "properties": { "id": "ak16904319", "mag": 1.4, "time": 1506369740689, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.5073, 60.0082, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16904318", "mag": 1.1, "time": 1506369510333, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5651, 61.4244, 63.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16904316", "mag": 1.1, "time": 1506368211425, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.7001, 61.5145, 4.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aukb", "mag": 4.3, "time": 1506368143480, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -127.1586, 40.3587, 11.36 ] } }, +{ "type": "Feature", "properties": { "id": "ak16904315", "mag": 1.2, "time": 1506367996393, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.8124, 59.8382, 15.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898871", "mag": 1.41, "time": 1506367887720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.785167, 38.8375, 1.88 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988695", "mag": 2.2, "time": 1506366990125, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 179.3689, 51.4218, 56.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci37166748", "mag": 1.04, "time": 1506366454300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.018667, 33.163167, -0.77 ] } }, +{ "type": "Feature", "properties": { "id": "hv61921056", "mag": 2.06, "time": 1506366154290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.950667, 19.540833, 15.491 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903722", "mag": 2.0, "time": 1506365944635, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.478, 51.697, 15.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010408", "mag": 1.27, "time": 1506365436790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.4445, 35.5745, 10.25 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010416", "mag": 1.17, "time": 1506365362690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.862667, 34.343333, -1.71 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249527", "mag": 1.29, "time": 1506365138370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.712833, 41.8725, 4.98 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903609", "mag": 2.1, "time": 1506365025587, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8085, 63.1578, 132.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010400", "mag": 1.04, "time": 1506364534100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.790833, 33.495667, 4.4 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606969", "mag": 1.1, "time": 1506364516065, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.689, 40.0864, 4.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903599", "mag": 2.5, "time": 1506364456407, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.8848, 59.5329, 96.9 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257649", "mag": 1.4, "time": 1506364202040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5255, 46.866667, 10.23 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898846", "mag": 1.62, "time": 1506364136870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.781833, 36.209, 7.55 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903591", "mag": 1.5, "time": 1506363943453, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.7347, 60.3302, 112.7 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257644", "mag": 1.05, "time": 1506363692190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.525167, 46.8665, 10.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010376", "mag": 1.42, "time": 1506363664230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.792667, 33.4945, 4.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aufz", "mag": 5.1, "time": 1506363043200, "felt": null, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 106.3876, -5.9298, 150.05 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898836", "mag": 1.32, "time": 1506362896010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.104, 37.324, -0.31 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903584", "mag": 1.0, "time": 1506362694028, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -138.2167, 63.9342, 1.9 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257639", "mag": 1.36, "time": 1506362284340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.615667, 46.316833, -2.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903579", "mag": 2.0, "time": 1506362237262, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.1637, 59.6819, 106.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898821", "mag": 1.99, "time": 1506361978590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.778667, 36.215667, 8.08 ] } }, +{ "type": "Feature", "properties": { "id": "us2000auf8", "mag": 3.0, "time": 1506361091820, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -127.3303, 40.4414, 11.43 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010336", "mag": 2.11, "time": 1506360496580, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.797167, 33.486667, 3.04 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988686", "mag": 1.5, "time": 1506360479843, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.7769, 51.9886, 24.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010328", "mag": 1.51, "time": 1506359920880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.977, 33.995333, 18.14 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988684", "mag": 1.6, "time": 1506359020522, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.4355, 59.7613, 127.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898791", "mag": 1.48, "time": 1506357667280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.679333, 40.288667, 4.66 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898786", "mag": 1.55, "time": 1506357321970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.322, 35.752333, 11.93 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898781", "mag": 1.12, "time": 1506356229990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.811333, 38.794833, 2.79 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010256", "mag": 1.04, "time": 1506354566340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.858833, 33.8575, 16.19 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010272", "mag": 2.41, "time": 1506354509850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.9285, 31.688833, 11.63 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257609", "mag": 1.3, "time": 1506354504500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.534667, 46.896, 11.48 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257604", "mag": 1.12, "time": 1506354406140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.531833, 46.867, 11.31 ] } }, +{ "type": "Feature", "properties": { "id": "ak16902391", "mag": 1.7, "time": 1506354336298, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8601, 62.0271, 60.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16902390", "mag": 1.1, "time": 1506354175816, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.3984, 60.1663, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16901812", "mag": 1.4, "time": 1506353222973, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.1565, 60.3908, 0.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16901813", "mag": 1.3, "time": 1506353183037, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.6264, 58.8255, 1.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16901809", "mag": 2.0, "time": 1506352267382, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.0949, 59.636, 10.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aucr", "mag": 4.6, "time": 1506352047620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 167.4691, -14.8531, 132.07 ] } }, +{ "type": "Feature", "properties": { "id": "ak16901806", "mag": 1.8, "time": 1506351538258, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.8449, 59.8126, 1.3 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257594", "mag": 0.98, "time": 1506349616550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.521333, 46.870833, 11.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010208", "mag": 1.21, "time": 1506348868740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.552, 33.526167, 13.79 ] } }, +{ "type": "Feature", "properties": { "id": "ak16901226", "mag": 1.1, "time": 1506348768479, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2671, 59.9538, 54.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aubr", "mag": 4.6, "time": 1506348737440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 167.0258, -12.6224, 229.97 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010200", "mag": 1.19, "time": 1506348702870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.953833, 34.8405, 11.97 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aubf", "mag": 4.4, "time": 1506348571430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.1777, 15.5423, 60.99 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898721", "mag": 1.03, "time": 1506348240990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.838333, 38.837334, 1.55 ] } }, +{ "type": "Feature", "properties": { "id": "ak16901214", "mag": 2.7, "time": 1506348231637, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.0448, 63.3492, 76.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aub9", "mag": 4.3, "time": 1506347727000, "felt": 65, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -71.99, -32.683, 24.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898706", "mag": 1.78, "time": 1506347531490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.838, 38.837833, 1.83 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010176", "mag": 0.96, "time": 1506346983830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.271667, 33.976667, 5.12 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aubt", "mag": 4.7, "time": 1506346771440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 178.6657, -38.3887, 23.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988672", "mag": 1.9, "time": 1506346449512, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.0765, 51.5898, 46.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16901206", "mag": 2.2, "time": 1506346185448, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.7016, 61.5212, 15.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16901204", "mag": 1.6, "time": 1506346082012, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.4545, 63.1289, 110.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898686", "mag": 1.5, "time": 1506345854120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.787167, 36.211667, 7.46 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988669", "mag": 1.8, "time": 1506344531244, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.2595, 53.699, 44.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16901203", "mag": 1.5, "time": 1506343558401, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.1793, 57.6776, 1.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898666", "mag": 1.04, "time": 1506343096950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.862667, 37.613167, 7.06 ] } }, +{ "type": "Feature", "properties": { "id": "ak16900637", "mag": 2.0, "time": 1506342621159, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.2424, 60.321, 83.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010152", "mag": 1.32, "time": 1506342413630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.241667, 34.439, 7.98 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aua8", "mag": 4.6, "time": 1506342291600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -71.282, -28.2916, 30.33 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898661", "mag": 1.86, "time": 1506342035450, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.000167, 36.431, -0.28 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010136", "mag": 1.46, "time": 1506341314650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.559, 35.341833, 7.37 ] } }, +{ "type": "Feature", "properties": { "id": "ak16900622", "mag": 1.0, "time": 1506340661643, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.7013, 64.8764, 7.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0h7", "mag": 4.2, "time": 1506340490190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 138.5087, 34.8799, 210.56 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898636", "mag": 1.46, "time": 1506340210490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.256667, 36.100167, 9.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0hp", "mag": 4.2, "time": 1506340162430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4582, -17.8551, 595.96 ] } }, +{ "type": "Feature", "properties": { "id": "us2000au9u", "mag": 4.6, "time": 1506340077990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4978, -17.9975, 539.99 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988664", "mag": 1.8, "time": 1506339965395, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4489, 51.676, 14.4 ] } }, +{ "type": "Feature", "properties": { "id": "hv61920741", "mag": 2.06, "time": 1506339899560, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.473667, 19.201667, 36.657 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010120", "mag": 0.99, "time": 1506339434380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.471167, 34.247833, 12.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16900621", "mag": 1.0, "time": 1506338627047, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.3115, 62.9535, 74.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898616", "mag": 2.36, "time": 1506338018430, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.938333, 37.838667, 4.07 ] } }, +{ "type": "Feature", "properties": { "id": "hv61920671", "mag": 1.81, "time": 1506336741780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.023667, 19.815, 11.479 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257584", "mag": 1.42, "time": 1506336624590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.521667, 46.869333, 11.15 ] } }, +{ "type": "Feature", "properties": { "id": "ak16900062", "mag": 1.8, "time": 1506336050720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.8893, 60.3211, 15.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010104", "mag": 1.06, "time": 1506335970890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.7915, 33.506667, 6.39 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898601", "mag": 0.95, "time": 1506335637390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.6475, 37.476667, 8.18 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898596", "mag": 1.23, "time": 1506335593850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.2805, 36.094, 6.76 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898591", "mag": 1.04, "time": 1506335405570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.839333, 38.843166, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000au8v", "mag": 4.9, "time": 1506334920720, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 139.9741, -3.5898, 72.65 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606909", "mag": 1.4, "time": 1506334911790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.943, 37.551, 8.3 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257579", "mag": 1.3, "time": 1506333510580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.523833, 46.872333, 11.79 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257574", "mag": 0.99, "time": 1506333384010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.523, 46.875167, 11.91 ] } }, +{ "type": "Feature", "properties": { "id": "us2000au8b", "mag": 5.0, "time": 1506332531610, "felt": null, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 154.0023, -5.3939, 63.28 ] } }, +{ "type": "Feature", "properties": { "id": "ak16899481", "mag": 1.2, "time": 1506332463619, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.8097, 60.337, 8.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16899478", "mag": 2.7, "time": 1506332457083, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.9674, 51.7565, 11.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16899480", "mag": 2.7, "time": 1506332456973, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.9649, 51.7427, 10.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898561", "mag": 1.34, "time": 1506332073270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.401667, 37.650667, 3.17 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257569", "mag": 2.91, "time": 1506332057970, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.525833, 46.879333, 11.49 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606905", "mag": 1.5, "time": 1506331668203, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9249, 38.3947, 7.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010072", "mag": 1.11, "time": 1506331415690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.790167, 33.497667, 5.47 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988657", "mag": 1.9, "time": 1506331001341, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4079, 51.6208, 15.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16899468", "mag": 1.4, "time": 1506330891437, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3579, 60.2131, 58.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16899467", "mag": 1.1, "time": 1506330692323, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.4142, 68.5865, 13.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16899465", "mag": 1.0, "time": 1506330113229, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.991, 61.1695, 1.9 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606904", "mag": 2.5, "time": 1506329813575, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.1098, 39.0988, 9.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16899462", "mag": 1.3, "time": 1506329610880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.9036, 64.8595, 12.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010048", "mag": 1.15, "time": 1506329091670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.815, 33.9555, 13.94 ] } }, +{ "type": "Feature", "properties": { "id": "us2000au7c", "mag": 3.5, "time": 1506329082460, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5238, 46.8486, 10.68 ] } }, +{ "type": "Feature", "properties": { "id": "ci38010040", "mag": 1.01, "time": 1506328796420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.568, 35.1735, 8.56 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606901", "mag": 1.2, "time": 1506328748981, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8911, 38.3811, 7.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16898909", "mag": 1.4, "time": 1506327817672, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.2932, 60.6736, 39.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988651", "mag": 1.6, "time": 1506327629626, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.8348, 59.5881, 89.7 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249397", "mag": 2.17, "time": 1506327209020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.448333, 38.993, -0.41 ] } }, +{ "type": "Feature", "properties": { "id": "ak16898901", "mag": 1.1, "time": 1506326924743, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.6407, 58.3143, 7.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000au6h", "mag": 4.7, "time": 1506326546500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 129.4008, -4.8417, 219.24 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249392", "mag": 1.79, "time": 1506326456200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.448, 42.620667, 6.55 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70235773", "mag": 2.04, "time": 1506326285610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.968667, 37.281833, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000au5z", "mag": 4.4, "time": 1506325840560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.7801, 14.8764, 57.41 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898491", "mag": 0.95, "time": 1506325310440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.818667, 37.478667, 0.05 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898486", "mag": 1.27, "time": 1506324949470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8175, 37.479333, 0.19 ] } }, +{ "type": "Feature", "properties": { "id": "ak16898346", "mag": 2.1, "time": 1506324898662, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -160.5224, 64.5882, 8.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000au5p", "mag": 4.4, "time": 1506324432650, "felt": 5, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -71.5244, -30.022, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000au5l", "mag": 4.5, "time": 1506324225060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.1793, 15.5215, 66.49 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898461", "mag": 1.64, "time": 1506323849520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.818167, 37.478667, 0.73 ] } }, +{ "type": "Feature", "properties": { "id": "us2000au5i", "mag": 4.6, "time": 1506323785060, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 106.9645, -8.3755, 34.69 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898456", "mag": 1.01, "time": 1506323761220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.818833, 37.478167, 0.69 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606939", "mag": 1.6, "time": 1506320868071, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.5993, 41.6963, 11.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988646", "mag": 1.6, "time": 1506320845663, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.7721, 59.5535, 80.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci38009968", "mag": 1.23, "time": 1506320510170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.738333, 33.655, 17.08 ] } }, +{ "type": "Feature", "properties": { "id": "us2000au57", "mag": 5.0, "time": 1506320285610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -25.7407, -59.0289, 23.15 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606937", "mag": 1.7, "time": 1506320281288, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.604, 41.7004, 6.9 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257544", "mag": 1.02, "time": 1506320165840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.538333, 46.891333, 11.64 ] } }, +{ "type": "Feature", "properties": { "id": "ak16897784", "mag": 1.7, "time": 1506319825200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.9967, 59.5158, 86.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16897782", "mag": 1.0, "time": 1506319406475, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.2438, 65.7781, 4.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16897779", "mag": 1.8, "time": 1506318873463, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.4148, 69.0584, 10.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898431", "mag": 2.32, "time": 1506318557110, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.909, 37.334167, 8.51 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898406", "mag": 1.9, "time": 1506317549980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.705833, 39.697, 8.09 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988640", "mag": 1.4, "time": 1506317208929, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.0479, 57.5544, 76.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988639", "mag": 1.2, "time": 1506316463527, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9489, 61.4034, 66.1 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606934", "mag": 1.4, "time": 1506315296099, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.8855, 37.2234, 7.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000b0hn", "mag": 4.2, "time": 1506314791590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -27.4466, -60.0959, 87.69 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898391", "mag": 0.97, "time": 1506314750800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.80867, 38.800999, 1.95 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898386", "mag": 2.07, "time": 1506314732630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.810833, 38.797667, 3.49 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898381", "mag": 1.3, "time": 1506314425330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.1325, 38.050167, 2.51 ] } }, +{ "type": "Feature", "properties": { "id": "ak16897226", "mag": 1.1, "time": 1506314336648, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.1369, 63.4162, 5.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000au3u", "mag": 4.3, "time": 1506313752770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7839, 15.5489, 36.62 ] } }, +{ "type": "Feature", "properties": { "id": "ak16897223", "mag": 1.5, "time": 1506313722965, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5906, 61.3427, 45.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16897221", "mag": 1.1, "time": 1506313193707, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.457, 63.4294, 4.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988635", "mag": 1.2, "time": 1506312840546, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.0928, 61.1303, 26.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988634", "mag": 1.1, "time": 1506312758288, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.7179, 62.8463, 7.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898366", "mag": 1.09, "time": 1506312288130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.797501, 38.824165, 1.31 ] } }, +{ "type": "Feature", "properties": { "id": "ak16897219", "mag": 1.1, "time": 1506311801540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.8303, 63.2243, 16.3 ] } }, +{ "type": "Feature", "properties": { "id": "uw61333436", "mag": 1.41, "time": 1506311554000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.943833, 48.589333, 4.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16896672", "mag": 2.4, "time": 1506311539840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6826, 63.2689, 133.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci38009904", "mag": 1.71, "time": 1506311193160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.813167, 34.048833, 13.41 ] } }, +{ "type": "Feature", "properties": { "id": "ak16896671", "mag": 1.0, "time": 1506310652342, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.6095, 62.9432, 11.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci38009840", "mag": 1.15, "time": 1506308854410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.765333, 33.325667, 12.51 ] } }, +{ "type": "Feature", "properties": { "id": "ak16896670", "mag": 1.3, "time": 1506308756498, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.6787, 59.995, 9.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16896669", "mag": 1.3, "time": 1506308490557, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.667, 59.9936, 9.8 ] } }, +{ "type": "Feature", "properties": { "id": "hv61920451", "mag": 2.11, "time": 1506307247260, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.050167, 19.765, 47.26 ] } }, +{ "type": "Feature", "properties": { "id": "ak16896663", "mag": 1.7, "time": 1506306347139, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.57, 59.4416, 74.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16896659", "mag": 1.5, "time": 1506306011000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.5629, 61.3391, 37.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16896656", "mag": 1.3, "time": 1506306004481, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.1978, 60.2569, 10.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16896653", "mag": 1.8, "time": 1506305432732, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.6915, 61.3592, 87.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988622", "mag": 2.2, "time": 1506305398552, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -162.4539, 55.424, 127.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898321", "mag": 0.97, "time": 1506303023560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.821, 37.470667, 1.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci38009824", "mag": 1.77, "time": 1506302722490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.721333, 32.171167, -0.08 ] } }, +{ "type": "Feature", "properties": { "id": "us2000au34", "mag": 4.2, "time": 1506301011430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.6458, 15.9582, 41.89 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898311", "mag": 1.53, "time": 1506300409700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.760333, 38.787333, 2.66 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898316", "mag": 1.17, "time": 1506300389070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.902833, 37.434167, 1.61 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249337", "mag": 1.05, "time": 1506300187150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.028, 44.797667, 10.68 ] } }, +{ "type": "Feature", "properties": { "id": "ak16896106", "mag": 1.8, "time": 1506299319432, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0832, 61.9049, 66.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16895566", "mag": 1.9, "time": 1506298140072, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.9051, 57.7026, 76.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16988619", "mag": 1.6, "time": 1506298131890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.9559, 60.0816, 113.8 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606884", "mag": 1.4, "time": 1506297047630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.0863, 37.3768, 7.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000au2t", "mag": 4.6, "time": 1506295898530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 130.3868, 31.2471, 159.23 ] } }, +{ "type": "Feature", "properties": { "id": "us2000au2s", "mag": 4.7, "time": 1506295771740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.3651, 15.6767, 54.03 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249317", "mag": 2.04, "time": 1506295039370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.424667, 42.575667, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935438", "mag": 1.4, "time": 1506294396969, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.934, 60.3588, 65.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898291", "mag": 1.5, "time": 1506294312930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.799167, 37.544833, 8.63 ] } }, +{ "type": "Feature", "properties": { "id": "ak16895561", "mag": 1.1, "time": 1506294004090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.0019, 62.1675, 14.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16895559", "mag": 1.7, "time": 1506293152617, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9808, 60.2626, 58.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898281", "mag": 1.51, "time": 1506291814030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.123, 38.044833, 2.62 ] } }, +{ "type": "Feature", "properties": { "id": "ak16895553", "mag": 2.2, "time": 1506291209658, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.9667, 58.2749, 2.3 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249297", "mag": 2.2, "time": 1506289719780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.027, 44.7975, 11.07 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898251", "mag": 1.06, "time": 1506289376180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.80867, 38.824501, 1.89 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606863", "mag": 1.6, "time": 1506289302497, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.1188, 37.3786, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16895018", "mag": 1.1, "time": 1506289187928, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.5309, 62.2207, 4.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898246", "mag": 1.11, "time": 1506288942820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8205, 37.474667, -0.27 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898241", "mag": 1.11, "time": 1506288826190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.819667, 37.477167, 0.62 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935433", "mag": 1.6, "time": 1506288360789, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.4754, 58.4123, 46.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935432", "mag": 2.5, "time": 1506287912932, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.0291, 52.8069, 25.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16895001", "mag": 2.4, "time": 1506287325387, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.3822, 59.9552, 133.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc71107574", "mag": 1.82, "time": 1506286958930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.1525, 38.965833, 3.75 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898236", "mag": 1.93, "time": 1506286874150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.849, 36.277667, 7.52 ] } }, +{ "type": "Feature", "properties": { "id": "ak16894980", "mag": 2.3, "time": 1506286457929, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.5039, 61.3116, 7.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000au0x", "mag": 4.1, "time": 1506285951620, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 137.7689, 33.0106, 343.06 ] } }, +{ "type": "Feature", "properties": { "id": "ak16894459", "mag": 1.4, "time": 1506285529465, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.7694, 59.8585, 7.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16894458", "mag": 3.5, "time": 1506285383201, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4213, 51.6336, 12.0 ] } }, +{ "type": "Feature", "properties": { "id": "hv61919931", "mag": 1.61, "time": 1506285094170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.2325, 19.4085, 26.679 ] } }, +{ "type": "Feature", "properties": { "id": "nm60207286", "mag": 1.46, "time": 1506284271340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -89.900667, 36.601833, 4.15 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898226", "mag": 1.94, "time": 1506284238360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.819, 37.476167, 0.74 ] } }, +{ "type": "Feature", "properties": { "id": "hv61919891", "mag": 2.03, "time": 1506284234210, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.278503, 19.407, 0.61 ] } }, +{ "type": "Feature", "properties": { "id": "us2000au0l", "mag": 5.0, "time": 1506283809180, "felt": 1, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 102.0863, -3.3959, 96.97 ] } }, +{ "type": "Feature", "properties": { "id": "ak16894448", "mag": 1.6, "time": 1506283718319, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1504, 61.1564, 63.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898216", "mag": 1.02, "time": 1506283590520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.826836, 38.841167, 1.21 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898211", "mag": 1.57, "time": 1506283158900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.113333, 38.042667, 2.45 ] } }, +{ "type": "Feature", "properties": { "id": "ak16894439", "mag": 2.3, "time": 1506283079762, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -179.7022, 51.6829, 87.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898206", "mag": 1.24, "time": 1506283017210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.777, 35.512, 0.74 ] } }, +{ "type": "Feature", "properties": { "id": "ci38009648", "mag": 0.95, "time": 1506282824500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.909333, 33.494, 13.21 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898196", "mag": 1.08, "time": 1506282126770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.81, 38.806833, 2.17 ] } }, +{ "type": "Feature", "properties": { "id": "ak16893920", "mag": 1.6, "time": 1506281844692, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.421, 62.907, 126.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898191", "mag": 1.6, "time": 1506281467240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.010167, 37.8015, 1.31 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898186", "mag": 2.26, "time": 1506281041390, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8185, 37.474833, -0.18 ] } }, +{ "type": "Feature", "properties": { "id": "uw61333306", "mag": 1.11, "time": 1506280827540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.812333, 48.284667, 12.62 ] } }, +{ "type": "Feature", "properties": { "id": "ci38009608", "mag": 1.3, "time": 1506280518180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.038, 33.0905, 2.11 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898176", "mag": 2.1, "time": 1506280314320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.818333, 37.475833, 0.78 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935422", "mag": 1.6, "time": 1506280296755, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.7731, 59.4501, 75.7 ] } }, +{ "type": "Feature", "properties": { "id": "hv61919726", "mag": 1.9, "time": 1506279270940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.4185, 19.110833, 41.621 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935421", "mag": 1.7, "time": 1506279143123, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.5363, 51.7438, 15.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16893907", "mag": 2.1, "time": 1506278978748, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.4135, 66.1088, 7.6 ] } }, +{ "type": "Feature", "properties": { "id": "uw61333296", "mag": 1.51, "time": 1506278869250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.581833, 47.593, 24.95 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898171", "mag": 1.13, "time": 1506278629370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.543167, 38.264833, 8.24 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606834", "mag": 1.5, "time": 1506278416314, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.885, 38.3509, 8.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci38009568", "mag": 1.23, "time": 1506278315340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.492333, 35.604833, 5.99 ] } }, +{ "type": "Feature", "properties": { "id": "ak16893391", "mag": 2.3, "time": 1506277628203, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -163.1998, 53.9184, 4.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16893390", "mag": 1.1, "time": 1506277025981, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.1933, 68.4549, 18.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16893388", "mag": 1.5, "time": 1506276710660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -144.3135, 68.0219, 2.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935416", "mag": 1.8, "time": 1506276357546, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -179.0551, 51.7225, 6.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898146", "mag": 1.54, "time": 1506276015270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.810333, 38.836, 1.98 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606827", "mag": 1.3, "time": 1506274049277, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.6642, 36.4428, 7.2 ] } }, +{ "type": "Feature", "properties": { "id": "uw61333281", "mag": 2.14, "time": 1506273261550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.502167, 49.447833, -0.06 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atz0", "mag": 4.3, "time": 1506273226630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -66.369, -22.6476, 261.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci38009520", "mag": 2.39, "time": 1506272765060, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.032333, 33.096333, 9.36 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898121", "mag": 1.18, "time": 1506272385880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.880667, 37.538167, 3.63 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atyw", "mag": 4.9, "time": 1506272236140, "felt": 49, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 27.2871, 36.912, 8.66 ] } }, +{ "type": "Feature", "properties": { "id": "uw61333276", "mag": 0.97, "time": 1506272212660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.677, 48.245, 8.69 ] } }, +{ "type": "Feature", "properties": { "id": "ci38009504", "mag": 1.59, "time": 1506272197880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.0285, 33.096, 10.24 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935414", "mag": 1.3, "time": 1506271871925, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3105, 62.8907, 109.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16892357", "mag": 1.5, "time": 1506271104455, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.2217, 60.9895, 43.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16892356", "mag": 1.0, "time": 1506270748541, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.7754, 66.4015, 0.3 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606816", "mag": 1.3, "time": 1506270455535, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.3547, 38.3427, 11.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16892349", "mag": 2.1, "time": 1506269387778, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.9052, 64.2272, 113.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16892348", "mag": 1.2, "time": 1506269350233, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.0305, 61.1531, 0.9 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249237", "mag": 1.72, "time": 1506268839820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -108.899, 38.3125, 1.61 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898066", "mag": 2.26, "time": 1506268374330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.820667, 37.604333, 4.11 ] } }, +{ "type": "Feature", "properties": { "id": "hv61919541", "mag": 2.2, "time": 1506268362680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.553, 19.106833, 58.134 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898071", "mag": 1.35, "time": 1506268343880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.978833, 37.602333, 0.75 ] } }, +{ "type": "Feature", "properties": { "id": "uw61333251", "mag": 0.99, "time": 1506267835060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.7565, 46.8405, 0.46 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249227", "mag": 1.55, "time": 1506267791100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.045667, 38.595, 10.17 ] } }, +{ "type": "Feature", "properties": { "id": "nc72898046", "mag": 1.31, "time": 1506267662950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.359333, 36.063833, 13.03 ] } }, +{ "type": "Feature", "properties": { "id": "uw61333241", "mag": 1.02, "time": 1506266858960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.7535, 46.835833, -0.06 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atyb", "mag": 4.2, "time": 1506265370020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9623, 16.5258, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16891829", "mag": 1.1, "time": 1506265012702, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.7832, 60.3293, 15.0 ] } }, +{ "type": "Feature", "properties": { "id": "uw61333221", "mag": 2.23, "time": 1506264885990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -124.458, 41.843167, 29.32 ] } }, +{ "type": "Feature", "properties": { "id": "ci38009392", "mag": 2.47, "time": 1506263949730, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.965667, 33.074, 3.01 ] } }, +{ "type": "Feature", "properties": { "id": "ak16891827", "mag": 1.6, "time": 1506263040480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.0762, 68.8735, 7.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935406", "mag": 1.9, "time": 1506262994682, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.4328, 58.9133, 119.1 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249217", "mag": 1.98, "time": 1506261948290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -108.8955, 38.308167, 2.5 ] } }, +{ "type": "Feature", "properties": { "id": "uw61333201", "mag": 1.01, "time": 1506261154820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.757333, 46.836833, 0.83 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606861", "mag": 1.0, "time": 1506260845911, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9076, 39.4306, 7.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16891323", "mag": 1.6, "time": 1506260101784, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.2725, 63.8369, 122.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935404", "mag": 1.9, "time": 1506259949572, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -175.9271, 51.4777, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16891318", "mag": 1.4, "time": 1506258938436, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.1228, 60.1784, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935403", "mag": 1.5, "time": 1506258927685, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.537, 59.7654, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awkh", "mag": 4.5, "time": 1506257940620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -176.6787, -21.4068, 6.58 ] } }, +{ "type": "Feature", "properties": { "id": "ci38009360", "mag": 1.01, "time": 1506257616920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.6935, 33.4475, 13.86 ] } }, +{ "type": "Feature", "properties": { "id": "hv61919476", "mag": 2.71, "time": 1506257049620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.326172, 19.400499, 6.36 ] } }, +{ "type": "Feature", "properties": { "id": "us2000azwe", "mag": 4.0, "time": 1506256906900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0503, 15.0164, 47.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935402", "mag": 1.3, "time": 1506256449894, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.1247, 62.5252, 67.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atx8", "mag": 4.5, "time": 1506256396240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -95.2151, 16.4456, 23.74 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awke", "mag": 4.3, "time": 1506254896510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -99.7664, -36.2005, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atx1", "mag": 4.3, "time": 1506253816940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.8221, 15.5422, 39.51 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897966", "mag": 1.94, "time": 1506252917940, "felt": 0, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.353833, 38.334333, 8.17 ] } }, +{ "type": "Feature", "properties": { "id": "ak16890316", "mag": 1.9, "time": 1506251419309, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.7084, 53.1628, 25.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935399", "mag": 2.2, "time": 1506251253254, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.9705, 58.4119, 157.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awkb", "mag": 4.4, "time": 1506250943050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.3134, -22.0133, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38009336", "mag": 1.4, "time": 1506250687150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.573, 33.198833, 3.26 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935398", "mag": 1.7, "time": 1506250678217, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.541, 51.1205, 34.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci37166588", "mag": 1.39, "time": 1506250675520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.547333, 33.281167, 1.13 ] } }, +{ "type": "Feature", "properties": { "id": "ci38009328", "mag": 1.47, "time": 1506250567750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.565833, 33.2015, 2.63 ] } }, +{ "type": "Feature", "properties": { "id": "us2000azw4", "mag": 4.0, "time": 1506250079340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2354, 15.2643, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897961", "mag": 1.0, "time": 1506249470110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.771164, 38.839333, 1.45 ] } }, +{ "type": "Feature", "properties": { "id": "ak16890295", "mag": 3.1, "time": 1506249009854, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.4939, 58.556, 142.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci38009320", "mag": 1.29, "time": 1506248967650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.577833, 33.1915, 3.45 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awka", "mag": 4.5, "time": 1506248797510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 101.4422, -3.5379, 76.33 ] } }, +{ "type": "Feature", "properties": { "id": "ak16889805", "mag": 1.1, "time": 1506248542391, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6804, 65.8304, 4.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16889804", "mag": 1.4, "time": 1506248465317, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.0578, 61.0579, 16.4 ] } }, +{ "type": "Feature", "properties": { "id": "hv61919431", "mag": 2.09, "time": 1506248237750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.282165, 19.41, 0.97 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atwe", "mag": 5.8, "time": 1506247572180, "felt": 12, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0996, 15.3335, 55.04 ] } }, +{ "type": "Feature", "properties": { "id": "ak16889794", "mag": 1.8, "time": 1506247473558, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.2731, 60.4252, 19.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16889792", "mag": 1.2, "time": 1506245981072, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.4789, 61.3979, 20.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935392", "mag": 2.2, "time": 1506245821194, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -176.1457, 52.299, 147.0 ] } }, +{ "type": "Feature", "properties": { "id": "uw61333151", "mag": 1.32, "time": 1506245720210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.3825, 46.455, 17.05 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atw1", "mag": 4.3, "time": 1506245575860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -86.8213, 11.9773, 72.06 ] } }, +{ "type": "Feature", "properties": { "id": "ak16889787", "mag": 1.5, "time": 1506245559319, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.1034, 61.6735, 30.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897941", "mag": 1.12, "time": 1506245298510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.880333, 37.529333, 3.01 ] } }, +{ "type": "Feature", "properties": { "id": "ak16889785", "mag": 1.4, "time": 1506245231368, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.6899, 61.5181, 15.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atvx", "mag": 4.0, "time": 1506245211400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -95.2276, 16.4152, 5.52 ] } }, +{ "type": "Feature", "properties": { "id": "ak16889300", "mag": 1.5, "time": 1506244274159, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0562, 62.8873, 108.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16889299", "mag": 1.7, "time": 1506243971468, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -142.0331, 60.0823, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16889298", "mag": 1.2, "time": 1506242695770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7525, 61.9971, 13.3 ] } }, +{ "type": "Feature", "properties": { "id": "hv61919256", "mag": 2.47, "time": 1506242595490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.234167, 19.416667, 25.716 ] } }, +{ "type": "Feature", "properties": { "id": "ak16889296", "mag": 1.5, "time": 1506242565319, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7169, 65.857, 21.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897921", "mag": 1.06, "time": 1506242001250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8435, 37.469667, 2.92 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897911", "mag": 2.08, "time": 1506241606310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.552333, 36.824833, 5.39 ] } }, +{ "type": "Feature", "properties": { "id": "ak16888862", "mag": 1.4, "time": 1506241109945, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2949, 62.9113, 106.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci38009280", "mag": 1.11, "time": 1506240906400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.0385, 33.996167, 14.68 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atvi", "mag": 2.6, "time": 1506240803150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4513, 42.6043, 5.23 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atvl", "mag": 4.0, "time": 1506239983840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9034, 16.4793, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16888812", "mag": 1.7, "time": 1506239643860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.1541, 59.6562, 69.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935382", "mag": 1.8, "time": 1506239506704, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.5249, 57.6124, 45.4 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257374", "mag": 1.2, "time": 1506238135570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.523333, 46.868, 11.76 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606790", "mag": 1.5, "time": 1506237560657, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.1999, 42.1841, 0.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atv2", "mag": 4.3, "time": 1506236966640, "felt": 7, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -71.864, -35.1565, 48.32 ] } }, +{ "type": "Feature", "properties": { "id": "ak16888374", "mag": 1.9, "time": 1506236724000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8397, 62.9467, 106.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16888373", "mag": 1.0, "time": 1506236683719, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.1115, 61.3903, 3.2 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249142", "mag": 1.26, "time": 1506236544020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.028333, 44.8, 10.63 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897871", "mag": 1.79, "time": 1506236124510, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.845333, 35.541667, 5.98 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897866", "mag": 2.12, "time": 1506235870210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.3545, 38.341333, 8.25 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935379", "mag": 1.6, "time": 1506235725999, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -176.5436, 51.4418, 21.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atuj", "mag": 4.6, "time": 1506235179700, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -75.5466, -14.3043, 33.52 ] } }, +{ "type": "Feature", "properties": { "id": "nc72903821", "mag": 1.02, "time": 1506234997060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.948167, 41.046333, 9.53 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897856", "mag": 1.71, "time": 1506234937540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8185, 37.471333, 1.25 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935378", "mag": 1.3, "time": 1506234863595, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9435, 61.261, 59.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci38009240", "mag": 0.99, "time": 1506234721960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.828167, 33.977667, 16.65 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935377", "mag": 3.3, "time": 1506234648623, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -173.3164, 50.4387, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16888327", "mag": 1.1, "time": 1506234051194, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.0067, 67.8619, 3.3 ] } }, +{ "type": "Feature", "properties": { "id": "hv61919146", "mag": 1.76, "time": 1506233551670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.438667, 19.110833, 40.565 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897836", "mag": 1.19, "time": 1506233494190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.879667, 37.536833, 3.32 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897831", "mag": 1.19, "time": 1506233212800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.880167, 37.536833, 3.36 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935375", "mag": 1.1, "time": 1506232927752, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.625, 63.077, 2.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16887898", "mag": 1.9, "time": 1506232339124, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4442, 51.588, 12.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atud", "mag": 4.6, "time": 1506232184760, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 122.3102, 23.9217, 19.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16887893", "mag": 1.8, "time": 1506231025885, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.6676, 61.5229, 16.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000attv", "mag": 3.2, "time": 1506230915380, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4686, 42.6086, 5.28 ] } }, +{ "type": "Feature", "properties": { "id": "ci38009080", "mag": 1.1, "time": 1506230493370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.65, 35.937333, 3.69 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897801", "mag": 1.86, "time": 1506230402950, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.880833, 37.5355, 3.17 ] } }, +{ "type": "Feature", "properties": { "id": "us2000attk", "mag": 4.4, "time": 1506229834430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.9698, 16.526, 14.16 ] } }, +{ "type": "Feature", "properties": { "id": "ak16887845", "mag": 2.2, "time": 1506229788458, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3609, 60.3798, 13.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci38009064", "mag": 2.54, "time": 1506229471590, "felt": 15, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.708833, 34.611167, -0.32 ] } }, +{ "type": "Feature", "properties": { "id": "ak16887419", "mag": 2.5, "time": 1506228712730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.1558, 57.6827, 0.6 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249092", "mag": 1.45, "time": 1506228417670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.041833, 38.6065, 7.11 ] } }, +{ "type": "Feature", "properties": { "id": "uu60013144", "mag": 2.65, "time": 1506227971910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.063667, 38.596667, 13.4 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249087", "mag": 3.34, "time": 1506227924130, "felt": 52, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.056, 38.615, 7.09 ] } }, +{ "type": "Feature", "properties": { "id": "ci38009040", "mag": 1.66, "time": 1506227707260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.754667, 32.691333, 7.72 ] } }, +{ "type": "Feature", "properties": { "id": "ak16887417", "mag": 1.4, "time": 1506227635748, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.4813, 59.9807, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "hv61919026", "mag": 1.76, "time": 1506225952210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.284164, 19.394167, 2.71 ] } }, +{ "type": "Feature", "properties": { "id": "hv61918996", "mag": 1.99, "time": 1506224898090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.28067, 19.403999, 1.29 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atsq", "mag": 4.1, "time": 1506223896740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -69.2705, -18.0175, 148.09 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935368", "mag": 2.3, "time": 1506222958411, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -176.4834, 51.3236, 13.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16886952", "mag": 1.2, "time": 1506222874628, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.387, 59.9979, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nm60207271", "mag": 1.17, "time": 1506222175440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -89.522833, 36.477167, 7.22 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897746", "mag": 1.28, "time": 1506221915120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.720833, 38.788, 2.34 ] } }, +{ "type": "Feature", "properties": { "id": "ak16886490", "mag": 1.1, "time": 1506220290807, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.3418, 62.9812, 77.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atse", "mag": 4.6, "time": 1506220200040, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -71.2801, -27.8834, 30.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935365", "mag": 1.8, "time": 1506220032447, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.1268, 57.8123, 70.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897736", "mag": 1.07, "time": 1506219512840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8245, 37.478833, 1.34 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935364", "mag": 2.4, "time": 1506219397177, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -169.8092, 52.1986, 20.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897726", "mag": 2.48, "time": 1506219108260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -125.023333, 40.3465, 9.33 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atsa", "mag": 4.2, "time": 1506218615340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.8425, 16.574, 39.83 ] } }, +{ "type": "Feature", "properties": { "id": "ak16935363", "mag": 1.0, "time": 1506217950145, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.5769, 68.6004, 0.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897701", "mag": 1.48, "time": 1506217326030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.819333, 37.475, -0.04 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897696", "mag": 1.19, "time": 1506216792400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.125, 36.5355, 3.43 ] } }, +{ "type": "Feature", "properties": { "id": "ak16886371", "mag": 2.1, "time": 1506216606733, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 179.8852, 51.4616, 53.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atrn", "mag": 3.8, "time": 1506215497620, "felt": 67, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.1371, 36.3727, 2.82 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897686", "mag": 2.17, "time": 1506215076790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.141167, 36.555, 2.89 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008976", "mag": 1.32, "time": 1506215071310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.450333, 34.2865, 7.66 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atrk", "mag": 5.0, "time": 1506214584220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 161.7808, -10.6598, 47.61 ] } }, +{ "type": "Feature", "properties": { "id": "ak16885992", "mag": 2.0, "time": 1506214179876, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6803, 63.2188, 129.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008968", "mag": 1.0, "time": 1506214163490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.8005, 33.996, 18.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16885991", "mag": 1.4, "time": 1506214156491, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.6167, 63.06, 7.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16885975", "mag": 2.0, "time": 1506213434632, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.5807, 63.0643, 7.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16885911", "mag": 1.9, "time": 1506213142249, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.5965, 63.0635, 4.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atre", "mag": 4.4, "time": 1506212946200, "felt": 13, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -88.7877, 12.9849, 60.16 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897676", "mag": 1.44, "time": 1506212851640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.836167, 37.574667, 1.65 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008928", "mag": 1.02, "time": 1506212597460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.178333, 33.195833, 6.76 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008920", "mag": 1.07, "time": 1506212251010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.430333, 34.0525, 9.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16885578", "mag": 1.8, "time": 1506211566495, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.6255, 61.4518, 71.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16885576", "mag": 1.5, "time": 1506211049943, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.5978, 61.5229, 17.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16885547", "mag": 1.3, "time": 1506210780241, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.6346, 63.8335, 106.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16885533", "mag": 1.6, "time": 1506209676573, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.5334, 61.8507, 43.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897656", "mag": 1.03, "time": 1506208996140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7145, 38.772667, 2.47 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008912", "mag": 1.4, "time": 1506208905320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.801167, 33.9745, 17.62 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008904", "mag": 1.35, "time": 1506208456300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.924333, 33.9845, 4.74 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atqq", "mag": 4.5, "time": 1506207994550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9873, 16.6593, 8.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16885149", "mag": 1.0, "time": 1506207804984, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3702, 64.9969, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "uu60249057", "mag": 2.12, "time": 1506207074140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.304, 44.720667, 6.11 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897646", "mag": 1.23, "time": 1506206872800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.735333, 38.787167, 1.28 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atq4", "mag": 4.6, "time": 1506204121620, "felt": 194, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -71.616, -33.7421, 44.72 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008864", "mag": 1.58, "time": 1506203611410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.609, 33.181333, 2.86 ] } }, +{ "type": "Feature", "properties": { "id": "ak16884706", "mag": 3.1, "time": 1506202930250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 178.1771, 51.8267, 132.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atpq", "mag": 4.9, "time": 1506201617890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 124.82, 7.5438, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atpp", "mag": 4.9, "time": 1506201494980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 124.8199, 7.5946, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16884645", "mag": 1.0, "time": 1506201077397, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.96, 64.7531, 1.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atpb", "mag": 5.7, "time": 1506199628760, "felt": 53, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 124.8736, 7.6285, 31.39 ] } }, +{ "type": "Feature", "properties": { "id": "ak16884300", "mag": 2.8, "time": 1506199486287, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -169.6652, 52.5903, 67.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897611", "mag": 1.26, "time": 1506199458450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.821667, 37.604333, 4.01 ] } }, +{ "type": "Feature", "properties": { "id": "ak16884298", "mag": 1.2, "time": 1506198439700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.5445, 59.7818, 0.1 ] } }, +{ "type": "Feature", "properties": { "id": "uw61332966", "mag": 1.38, "time": 1506197756870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.684333, 48.248, 9.29 ] } }, +{ "type": "Feature", "properties": { "id": "ak16884247", "mag": 2.2, "time": 1506197594492, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.0461, 51.8485, 92.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16883936", "mag": 1.0, "time": 1506196999226, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.8099, 64.7452, 10.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008816", "mag": 1.2, "time": 1506196919720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.403833, 34.223333, 11.34 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897586", "mag": 2.51, "time": 1506196446140, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -124.396167, 40.494333, 25.08 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897566", "mag": 2.07, "time": 1506194792800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.835833, 37.572667, 1.63 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897561", "mag": 1.83, "time": 1506194678430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8365, 37.574, 1.71 ] } }, +{ "type": "Feature", "properties": { "id": "ak16883864", "mag": 2.8, "time": 1506194224396, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -175.8992, 51.3293, 31.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16883866", "mag": 1.0, "time": 1506193955730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.8833, 59.8983, 14.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897541", "mag": 1.74, "time": 1506193009290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.820833, 37.6045, 4.22 ] } }, +{ "type": "Feature", "properties": { "id": "ak16883553", "mag": 1.2, "time": 1506192900100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.4017, 65.5315, 14.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16883554", "mag": 1.2, "time": 1506192680980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.0611, 67.1099, 2.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atnx", "mag": 2.6, "time": 1506192601240, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4214, 42.5566, 9.03 ] } }, +{ "type": "Feature", "properties": { "id": "ak16883552", "mag": 1.1, "time": 1506192410113, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.197, 60.3011, 0.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897531", "mag": 2.28, "time": 1506191594770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.821667, 37.604, 4.22 ] } }, +{ "type": "Feature", "properties": { "id": "us2000augr", "mag": 4.5, "time": 1506191531170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -138.4442, -11.942, 15.62 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008760", "mag": 1.23, "time": 1506190682920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.415167, 33.1465, 4.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008752", "mag": 1.14, "time": 1506190401470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.972, 33.217167, 7.81 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897521", "mag": 1.68, "time": 1506190013010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.811833, 38.821167, 1.49 ] } }, +{ "type": "Feature", "properties": { "id": "ak16883482", "mag": 1.4, "time": 1506189726896, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.742, 64.4224, 18.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16923786", "mag": 2.7, "time": 1506189654902, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -163.1544, 53.4208, 25.6 ] } }, +{ "type": "Feature", "properties": { "id": "hv61918336", "mag": 2.94, "time": 1506189242240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.611167, 19.4215, 2.482 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atn1", "mag": 4.4, "time": 1506188901480, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 125.1457, 7.0739, 96.15 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897511", "mag": 1.1, "time": 1506188786860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.7965, 37.484667, 7.75 ] } }, +{ "type": "Feature", "properties": { "id": "ak16883178", "mag": 2.9, "time": 1506188673480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.5715, 58.1668, 7.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16923784", "mag": 1.7, "time": 1506187667099, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.6425, 60.6215, 67.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atms", "mag": 5.0, "time": 1506187553100, "felt": 30, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -68.9096, -30.7535, 117.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008720", "mag": 1.14, "time": 1506187127550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.4515, 34.231833, 12.91 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897476", "mag": 2.49, "time": 1506186613660, "felt": 6, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.3425, 36.714, -0.57 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897471", "mag": 1.19, "time": 1506186452260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.773834, 38.833832, 1.91 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008696", "mag": 1.09, "time": 1506186268310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.848333, 36.183167, 3.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008688", "mag": 1.35, "time": 1506185983910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.845167, 36.179667, 2.43 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897466", "mag": 1.85, "time": 1506185948480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.807, 38.052667, 0.81 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atmg", "mag": 4.4, "time": 1506185133990, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 71.1291, 36.4703, 91.01 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atmf", "mag": 4.5, "time": 1506184783190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -69.21, -28.772, 131.62 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897451", "mag": 1.44, "time": 1506184758630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.9955, 36.407667, 6.86 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008672", "mag": 2.68, "time": 1506184689590, "felt": 16, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.8015, 33.498333, 5.63 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008664", "mag": 1.11, "time": 1506184563870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.261167, 34.006833, 14.43 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atmc", "mag": 2.7, "time": 1506184527900, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4447, 42.5711, 9.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atma", "mag": 4.4, "time": 1506183893420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7171, 16.8156, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897441", "mag": 1.31, "time": 1506183491090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.606833, 37.170833, 12.95 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897436", "mag": 1.56, "time": 1506183390100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.606833, 37.198667, 10.68 ] } }, +{ "type": "Feature", "properties": { "id": "ak16882778", "mag": 2.6, "time": 1506183338101, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.6342, 57.1033, 9.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16923782", "mag": 2.0, "time": 1506182696586, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.8058, 59.0921, 75.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16882769", "mag": 3.1, "time": 1506182496691, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -173.0149, 52.3026, 176.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atm1", "mag": 4.3, "time": 1506182042160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 62.7519, 26.1798, 45.69 ] } }, +{ "type": "Feature", "properties": { "id": "ak16882474", "mag": 1.9, "time": 1506181429544, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7141, 61.0689, 15.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16882473", "mag": 1.1, "time": 1506181415825, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.5959, 60.5708, 14.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897426", "mag": 1.24, "time": 1506180532690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.623667, 37.188167, 10.74 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008584", "mag": 1.58, "time": 1506180105990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.444, 33.030667, 2.87 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atlk", "mag": 3.8, "time": 1506180000610, "felt": 14, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4292, 42.5433, 9.91 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atlf", "mag": 4.2, "time": 1506179194220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -95.0107, 16.603, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257194", "mag": 1.15, "time": 1506178837080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.525833, 46.886, 12.66 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606739", "mag": 1.0, "time": 1506178325112, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.0924, 40.2311, 5.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008536", "mag": 1.59, "time": 1506177881730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.795667, 33.495667, 3.67 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atkr", "mag": 4.9, "time": 1506177106540, "felt": 5, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.8831, 16.6905, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atku", "mag": 4.2, "time": 1506176872070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.97, 16.7939, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897386", "mag": 1.06, "time": 1506176360420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.811667, 38.818667, 2.57 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008512", "mag": 2.34, "time": 1506176315810, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.0575, 34.503333, 8.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atkn", "mag": 4.4, "time": 1506176300040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -95.1269, 16.7434, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16882104", "mag": 1.1, "time": 1506175629079, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.8075, 60.3407, 9.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897361", "mag": 0.96, "time": 1506174820850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.612, 37.392833, 13.92 ] } }, +{ "type": "Feature", "properties": { "id": "ak16881826", "mag": 2.5, "time": 1506174802909, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.6324, 58.8539, 123.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008496", "mag": 1.78, "time": 1506174424760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.817167, 34.867667, 4.67 ] } }, +{ "type": "Feature", "properties": { "id": "ak16881795", "mag": 1.1, "time": 1506173527174, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.8881, 64.8661, 12.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atke", "mag": 5.1, "time": 1506173434140, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 120.8176, 13.6704, 193.27 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atk8", "mag": 4.8, "time": 1506173052110, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9123, 16.7308, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16881771", "mag": 1.2, "time": 1506172200912, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.8726, 64.8605, 11.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16881749", "mag": 1.6, "time": 1506171778198, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.8844, 64.8563, 10.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atjy", "mag": 4.3, "time": 1506171499860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 129.9043, -2.9658, 44.93 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248857", "mag": 1.35, "time": 1506171338590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.890833, 37.000833, 18.28 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atjv", "mag": 6.1, "time": 1506171182420, "felt": 203, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9509, 16.7732, 9.62 ] } }, +{ "type": "Feature", "properties": { "id": "ak16881467", "mag": 1.4, "time": 1506170949832, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.8768, 64.9158, 8.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16881459", "mag": 1.7, "time": 1506170669236, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.6941, 64.6752, 17.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16881453", "mag": 1.5, "time": 1506170369239, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.9047, 64.8585, 16.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atjm", "mag": 4.6, "time": 1506169519350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 142.1923, 31.1823, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avhc", "mag": 2.6, "time": 1506167877970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -175.84, 52.2553, 189.02 ] } }, +{ "type": "Feature", "properties": { "id": "ak16881171", "mag": 2.3, "time": 1506167030162, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -175.8612, 51.6605, 44.9 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248832", "mag": 1.05, "time": 1506167017860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.340667, 40.274333, 3.24 ] } }, +{ "type": "Feature", "properties": { "id": "us2000augc", "mag": 4.6, "time": 1506166612290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 154.9573, -5.8521, 181.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16881170", "mag": 1.2, "time": 1506166372386, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.7852, 62.5649, 5.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16881168", "mag": 1.3, "time": 1506166038103, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5567, 63.2977, 0.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897346", "mag": 1.79, "time": 1506165696260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.112333, 37.231, 6.72 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avha", "mag": 3.4, "time": 1506165671380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -170.4308, 52.2784, 36.52 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008448", "mag": 1.41, "time": 1506165347360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.561667, 32.957167, 8.78 ] } }, +{ "type": "Feature", "properties": { "id": "ak16881165", "mag": 1.3, "time": 1506165145820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.3968, 60.1913, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16881154", "mag": 1.7, "time": 1506164474729, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.4355, 60.0468, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16923760", "mag": 1.5, "time": 1506164269172, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.3627, 51.5307, 19.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atis", "mag": 5.8, "time": 1506163088980, "felt": 26, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.1625, 15.6979, 74.22 ] } }, +{ "type": "Feature", "properties": { "id": "ak16880880", "mag": 2.0, "time": 1506162923314, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.4514, 58.8323, 121.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16880879", "mag": 1.5, "time": 1506162509845, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.4379, 59.9894, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897331", "mag": 1.09, "time": 1506162381540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.827, 37.610667, 4.37 ] } }, +{ "type": "Feature", "properties": { "id": "ak16880874", "mag": 1.6, "time": 1506161778674, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.9513, 62.6833, 55.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16880872", "mag": 2.2, "time": 1506161709130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.2999, 57.8298, 119.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16880868", "mag": 1.9, "time": 1506161335096, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.0011, 60.342, 8.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16880864", "mag": 1.5, "time": 1506160533641, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2829, 64.8808, 8.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897316", "mag": 1.12, "time": 1506160300400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.288667, 36.670833, 2.66 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ati0", "mag": 4.5, "time": 1506158356450, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -77.7746, 9.1385, 52.29 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897301", "mag": 3.32, "time": 1506157219710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -127.0845, 40.348333, 11.62 ] } }, +{ "type": "Feature", "properties": { "id": "uw61332771", "mag": 1.35, "time": 1506157207660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.313333, 47.606333, 8.75 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897271", "mag": 1.14, "time": 1506156362630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.254167, 36.643167, 6.03 ] } }, +{ "type": "Feature", "properties": { "id": "ak16880667", "mag": 1.1, "time": 1506155808049, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.5764, 61.5311, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ati7", "mag": 3.5, "time": 1506155357560, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 129.0524, 41.3116, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atht", "mag": 4.7, "time": 1506154802240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 152.0272, 44.3731, 31.79 ] } }, +{ "type": "Feature", "properties": { "id": "ak16880659", "mag": 1.0, "time": 1506154668324, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -142.1159, 65.4383, 3.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16880589", "mag": 2.0, "time": 1506153946841, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.6279, 61.5946, 79.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897246", "mag": 1.31, "time": 1506153823970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.762, 38.794, 0.72 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008352", "mag": 1.63, "time": 1506153604550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.4425, 33.0265, 5.8 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606675", "mag": 1.2, "time": 1506152057931, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9167, 38.4054, 10.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16880394", "mag": 3.6, "time": 1506152017544, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -170.3853, 52.2081, 31.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16923747", "mag": 1.9, "time": 1506151958661, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4175, 51.6761, 16.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008344", "mag": 1.48, "time": 1506151638300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.324167, 33.310833, 12.5 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248802", "mag": 2.41, "time": 1506151450100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.419667, 42.565833, 9.15 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ath8", "mag": 4.1, "time": 1506151137510, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2976, 15.8203, 61.65 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897236", "mag": 1.32, "time": 1506151113910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.898167, 37.524833, 12.73 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ath6", "mag": 4.1, "time": 1506150769430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.3958, 15.2768, 10.51 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008328", "mag": 1.27, "time": 1506150100050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.200167, 33.893167, 7.86 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606672", "mag": 1.5, "time": 1506150086518, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.2696, 38.2952, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000augd", "mag": 4.4, "time": 1506150000550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 144.8812, 20.1804, 76.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008320", "mag": 1.19, "time": 1506149119830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.9395, 33.982167, 4.39 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atgz", "mag": 4.2, "time": 1506149095090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -87.0247, 10.6523, 19.49 ] } }, +{ "type": "Feature", "properties": { "id": "ak16880326", "mag": 2.0, "time": 1506149068802, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.0613, 61.3779, 34.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ath2", "mag": 4.7, "time": 1506149033340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 129.7584, -3.0863, 34.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16880327", "mag": 1.1, "time": 1506149006055, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.2865, 68.6023, 13.4 ] } }, +{ "type": "Feature", "properties": { "id": "uw61332671", "mag": 1.77, "time": 1506147857710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.281667, 47.7015, 25.73 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897231", "mag": 2.11, "time": 1506147638730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.6555, 36.061833, 9.09 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aug5", "mag": 4.5, "time": 1506146537200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -179.8683, -24.2891, 524.27 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008296", "mag": 1.25, "time": 1506146485640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.616, 33.586167, 13.04 ] } }, +{ "type": "Feature", "properties": { "id": "ak16880116", "mag": 1.8, "time": 1506145682289, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -142.2213, 66.2475, 7.6 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606730", "mag": 1.3, "time": 1506145648978, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.1876, 38.2127, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008288", "mag": 1.58, "time": 1506145525140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.4415, 32.5255, 16.12 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606667", "mag": 1.5, "time": 1506145236843, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.917, 38.3346, 11.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atgp", "mag": 4.5, "time": 1506143865490, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -74.7175, 9.7486, 52.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000athl", "mag": 4.4, "time": 1506143271620, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 108.9322, -8.2399, 66.53 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897216", "mag": 1.88, "time": 1506142958730, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.9835, 40.89, 15.76 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897211", "mag": 1.17, "time": 1506142616000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.827667, 38.837166, 1.66 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897201", "mag": 0.95, "time": 1506142430900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.848, 38.839168, 2.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897191", "mag": 1.9, "time": 1506141940330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.177333, 40.264333, 3.77 ] } }, +{ "type": "Feature", "properties": { "id": "ak16879870", "mag": 2.3, "time": 1506141876996, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.6246, 59.199, 103.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16879869", "mag": 1.3, "time": 1506141297637, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.7807, 60.3298, 7.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606723", "mag": 1.0, "time": 1506140560559, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.2867, 38.4929, 10.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008224", "mag": 0.95, "time": 1506140386650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.208667, 33.3405, 11.26 ] } }, +{ "type": "Feature", "properties": { "id": "ak16879830", "mag": 1.4, "time": 1506140318328, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2827, 60.4409, 47.8 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606722", "mag": 1.2, "time": 1506140002001, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9021, 38.3867, 7.8 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606720", "mag": 1.1, "time": 1506139980519, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.2929, 38.489, 10.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897176", "mag": 1.78, "time": 1506139907070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.285333, 38.488, 8.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897171", "mag": 1.19, "time": 1506139518870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.735336, 38.790001, 1.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897166", "mag": 2.9, "time": 1506138206720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -126.992667, 40.335333, 11.62 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atgc", "mag": 4.2, "time": 1506137667560, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9729, 15.6003, 33.69 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897161", "mag": 3.28, "time": 1506137168410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -127.014, 40.471167, 11.62 ] } }, +{ "type": "Feature", "properties": { "id": "ak16879595", "mag": 2.4, "time": 1506137087441, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.8458, 58.348, 0.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16923736", "mag": 1.3, "time": 1506135643558, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.0957, 61.7127, 43.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16879403", "mag": 1.0, "time": 1506135058360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4982, 63.0889, 5.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16923734", "mag": 2.5, "time": 1506133328382, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -161.4425, 54.2787, 25.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16879357", "mag": 2.6, "time": 1506132937319, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.3477, 59.8339, 130.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16879346", "mag": 2.2, "time": 1506132165090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.4939, 67.7172, 16.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16879344", "mag": 2.6, "time": 1506132016431, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -161.1196, 54.9637, 82.8 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606656", "mag": 1.3, "time": 1506130971840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.3283, 38.6945, 9.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897141", "mag": 2.05, "time": 1506130087910, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -124.4195, 40.470333, 27.65 ] } }, +{ "type": "Feature", "properties": { "id": "ak16879132", "mag": 1.4, "time": 1506129632041, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.0373, 62.0301, 10.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atfh", "mag": 2.6, "time": 1506129518070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4417, 42.5563, 10.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897136", "mag": 1.16, "time": 1506129465180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.888333, 36.006167, 8.34 ] } }, +{ "type": "Feature", "properties": { "id": "ak16879131", "mag": 1.2, "time": 1506128472934, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.7081, 62.2652, 36.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897126", "mag": 2.19, "time": 1506127820390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.640167, 36.048667, 19.79 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aug3", "mag": 4.3, "time": 1506127768780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 130.2316, -6.5899, 129.05 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atfc", "mag": 4.4, "time": 1506126533850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4878, -17.8955, 579.93 ] } }, +{ "type": "Feature", "properties": { "id": "ak16878940", "mag": 1.3, "time": 1506126488960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.4306, 62.433, 39.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16923727", "mag": 1.8, "time": 1506125768611, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.7156, 59.1725, 89.1 ] } }, +{ "type": "Feature", "properties": { "id": "uw61332606", "mag": 1.37, "time": 1506125724350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.8475, 47.767167, 17.62 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atf6", "mag": 4.6, "time": 1506125651480, "felt": 34, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 74.5944, 34.2131, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16923726", "mag": 1.0, "time": 1506125523162, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.4554, 62.0263, 40.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926133", "mag": 2.1, "time": 1506124308750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.1191, 56.3855, 12.5 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606641", "mag": 1.1, "time": 1506124233235, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9048, 38.3823, 7.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atex", "mag": 5.3, "time": 1506124170400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 141.0234, 31.3473, 31.02 ] } }, +{ "type": "Feature", "properties": { "id": "ak16878728", "mag": 1.1, "time": 1506123741185, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3949, 64.9801, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "uw61332586", "mag": 1.03, "time": 1506123697550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.176833, 48.224167, 9.44 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926129", "mag": 1.4, "time": 1506123469629, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -135.8468, 66.6906, 13.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16878722", "mag": 1.4, "time": 1506123273253, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -142.5552, 60.2789, 8.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awr8", "mag": 4.2, "time": 1506122891910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 144.1488, -4.6487, 111.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ateh", "mag": 4.9, "time": 1506122747420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 159.6233, -7.7533, 37.28 ] } }, +{ "type": "Feature", "properties": { "id": "uw61332576", "mag": 1.22, "time": 1506122597830, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.362, 45.695667, -0.73 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926127", "mag": 1.8, "time": 1506122331683, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.4507, 53.4966, 5.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897116", "mag": 3.91, "time": 1506122239050, "felt": 60, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -124.417333, 40.495333, 26.88 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897111", "mag": 2.5, "time": 1506122222600, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.119, 36.5365, 3.92 ] } }, +{ "type": "Feature", "properties": { "id": "ak16878700", "mag": 1.8, "time": 1506121093447, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.734, 61.0547, 12.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awr7", "mag": 4.8, "time": 1506120979560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -35.8191, 7.4851, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257104", "mag": 0.96, "time": 1506120805630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.649833, 45.463833, 2.97 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008136", "mag": 1.88, "time": 1506120529920, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.8015, 33.496833, 4.18 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897096", "mag": 1.12, "time": 1506120001160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.939167, 37.600667, 1.08 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awra", "mag": 4.0, "time": 1506119896150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 128.7982, -5.8817, 310.41 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926125", "mag": 2.1, "time": 1506118947000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.1588, 60.2166, 143.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008120", "mag": 1.02, "time": 1506118476380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.0015, 34.316333, 6.69 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897091", "mag": 1.46, "time": 1506118411060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.8605, 39.795333, 0.38 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926124", "mag": 1.8, "time": 1506118096316, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.2941, 60.3659, 4.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897081", "mag": 1.12, "time": 1506117239720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.262833, 36.6425, 4.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897086", "mag": 2.87, "time": 1506117196030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -126.983667, 40.3995, 16.96 ] } }, +{ "type": "Feature", "properties": { "id": "hv61917311", "mag": 1.89, "time": 1506116007530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.434662, 19.227833, 33.59 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926123", "mag": 1.1, "time": 1506115983704, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.6992, 61.5094, 7.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926121", "mag": 1.9, "time": 1506115445859, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.1112, 60.0903, 117.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926120", "mag": 1.1, "time": 1506115334031, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0777, 62.5847, 77.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awr9", "mag": 4.3, "time": 1506115308090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.1151, -17.7862, 593.28 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926119", "mag": 2.3, "time": 1506114986922, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.0025, 54.0581, 74.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926118", "mag": 1.7, "time": 1506114971248, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.8129, 59.8684, 52.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897066", "mag": 0.96, "time": 1506114595240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.793999, 38.820167, 2.73 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atdb", "mag": 2.4, "time": 1506114466770, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.7172, 36.3761, 4.22 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926117", "mag": 2.5, "time": 1506113979958, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -158.1399, 56.7494, 112.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16878294", "mag": 1.9, "time": 1506113817766, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.1371, 60.4549, 78.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16878292", "mag": 1.4, "time": 1506113608674, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.3651, 61.5158, 28.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16878288", "mag": 2.0, "time": 1506113191350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.6595, 59.6404, 74.9 ] } }, +{ "type": "Feature", "properties": { "id": "hv61917256", "mag": 1.43, "time": 1506112916300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.825667, 19.312167, 8.904 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atcg", "mag": 3.0, "time": 1506112409690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -126.6543, 40.4678, 10.42 ] } }, +{ "type": "Feature", "properties": { "id": "ak16878117", "mag": 1.1, "time": 1506111493188, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.4364, 62.2279, 3.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16878112", "mag": 1.8, "time": 1506111203565, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.6978, 58.82, 10.8 ] } }, +{ "type": "Feature", "properties": { "id": "nm60207231", "mag": 0.97, "time": 1506111124010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -89.499167, 36.239, 6.94 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atbf", "mag": 5.7, "time": 1506109815030, "felt": 112, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ -126.8342, 40.4144, 11.01 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606606", "mag": 1.7, "time": 1506109275519, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.0338, 40.677, 7.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897011", "mag": 1.34, "time": 1506108443760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.041, 35.58, -0.28 ] } }, +{ "type": "Feature", "properties": { "id": "ak16877921", "mag": 1.1, "time": 1506108429374, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.752, 61.522, 5.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008072", "mag": 1.35, "time": 1506108266330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.202333, 34.987667, -0.83 ] } }, +{ "type": "Feature", "properties": { "id": "nc72897001", "mag": 1.91, "time": 1506107768510, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7205, 38.773333, 1.82 ] } }, +{ "type": "Feature", "properties": { "id": "ak16877871", "mag": 1.9, "time": 1506107175373, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.7465, 59.9075, 2.4 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257054", "mag": 1.62, "time": 1506107025590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.474333, 46.006833, -2.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16877869", "mag": 1.6, "time": 1506107008752, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.4734, 63.1712, 116.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci38008032", "mag": 1.22, "time": 1506106977520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.345, 35.0535, -1.01 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atab", "mag": 4.5, "time": 1506106483030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 163.2943, 54.9226, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896976", "mag": 1.19, "time": 1506105877560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.816833, 37.4545, 1.72 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896966", "mag": 1.64, "time": 1506105469690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.945833, 41.046833, 10.15 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896961", "mag": 1.88, "time": 1506105394080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.951833, 41.047667, 13.46 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926108", "mag": 2.2, "time": 1506105113528, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.5222, 56.3354, 50.1 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248707", "mag": 1.68, "time": 1506104631990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.397333, 42.534833, 3.76 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007992", "mag": 1.55, "time": 1506104354710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.9245, 35.899167, 6.51 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926107", "mag": 1.2, "time": 1506103639337, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.7358, 61.509, 12.2 ] } }, +{ "type": "Feature", "properties": { "id": "hv61917106", "mag": 1.63, "time": 1506102792120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.303667, 18.980667, 12.732 ] } }, +{ "type": "Feature", "properties": { "id": "ak16877700", "mag": 1.7, "time": 1506102481165, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.8203, 53.8611, 6.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16877698", "mag": 1.6, "time": 1506102300688, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.8262, 53.8452, 5.6 ] } }, +{ "type": "Feature", "properties": { "id": "uw61332361", "mag": 1.6, "time": 1506102282810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.8865, 47.171, 14.87 ] } }, +{ "type": "Feature", "properties": { "id": "ak16877680", "mag": 1.9, "time": 1506102017646, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.8735, 62.7643, 9.8 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248702", "mag": 1.26, "time": 1506101951970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.430167, 42.589833, 6.39 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926103", "mag": 2.3, "time": 1506101692988, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -175.9282, 51.3815, 44.4 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248697", "mag": 2.15, "time": 1506100947090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4775, 42.630333, 2.79 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926102", "mag": 1.9, "time": 1506100904987, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2736, 59.4158, 101.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16877679", "mag": 1.1, "time": 1506100453436, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.9781, 63.2957, 76.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257039", "mag": 1.48, "time": 1506100139660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.555833, 46.892333, 9.34 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007944", "mag": 1.7, "time": 1506100079090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.656667, 34.638, 3.99 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248692", "mag": 1.13, "time": 1506099922660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.408833, 42.514, 6.63 ] } }, +{ "type": "Feature", "properties": { "id": "ak16877641", "mag": 3.4, "time": 1506099810694, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.7965, 62.8041, 16.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896921", "mag": 1.1, "time": 1506099607680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.816333, 38.808833, 2.84 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896916", "mag": 3.01, "time": 1506099251650, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -125.362167, 40.3915, 25.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16877640", "mag": 1.4, "time": 1506099120563, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -142.4377, 69.5097, 14.2 ] } }, +{ "type": "Feature", "properties": { "id": "hv61917081", "mag": 2.14, "time": 1506099100410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.043667, 19.653667, 42.069 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926098", "mag": 1.7, "time": 1506099097278, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.9448, 59.8191, 95.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci37166268", "mag": 1.03, "time": 1506097971820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.496667, 33.561167, -0.73 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007912", "mag": 1.01, "time": 1506097946840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.406, 33.502167, 13.49 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926097", "mag": 1.6, "time": 1506097726880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.164, 62.5769, 121.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896896", "mag": 0.95, "time": 1506097561860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.062, 35.522667, 1.15 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248682", "mag": 1.11, "time": 1506097353810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.413333, 42.546167, 4.8 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248677", "mag": 1.32, "time": 1506097004840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.424667, 42.595, 4.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896881", "mag": 1.04, "time": 1506096955860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.874667, 37.619833, 8.25 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896886", "mag": 3.06, "time": 1506096897270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -127.211833, 40.581333, 16.62 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248672", "mag": 1.72, "time": 1506096443230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.447833, 42.59, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007888", "mag": 1.36, "time": 1506095052550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.7965, 33.495167, 4.57 ] } }, +{ "type": "Feature", "properties": { "id": "ak16877477", "mag": 1.5, "time": 1506094830892, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.0265, 62.027, 12.7 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248667", "mag": 1.93, "time": 1506094359510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4395, 42.584333, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606574", "mag": 1.6, "time": 1506094148428, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9043, 38.3654, 6.9 ] } }, +{ "type": "Feature", "properties": { "id": "hv61917031", "mag": 1.65, "time": 1506094079130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.279333, 18.952333, 12.363 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248662", "mag": 2.05, "time": 1506093605010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.456167, 42.602333, 3.17 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at3w", "mag": 2.6, "time": 1506093461490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.4231, 36.6952, 7.14 ] } }, +{ "type": "Feature", "properties": { "id": "ak16877317", "mag": 1.7, "time": 1506093374261, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3603, 60.6882, 68.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926094", "mag": 2.1, "time": 1506093004583, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -162.8719, 54.5409, 50.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16877316", "mag": 1.4, "time": 1506092949248, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -158.2867, 67.5064, 1.5 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606471", "mag": 1.3, "time": 1506092280598, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.1113, 38.2958, 6.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awqu", "mag": 4.3, "time": 1506092048390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 121.5573, 18.5841, 62.16 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926092", "mag": 1.3, "time": 1506091602226, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.7703, 57.7311, 11.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16877311", "mag": 1.7, "time": 1506091080231, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.9318, 61.3129, 6.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awqt", "mag": 4.5, "time": 1506090800020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -179.4373, -23.752, 560.01 ] } }, +{ "type": "Feature", "properties": { "id": "nc72904206", "mag": 1.3, "time": 1506089865090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.585167, 40.4755, 15.05 ] } }, +{ "type": "Feature", "properties": { "id": "uw61309452", "mag": 2.05, "time": 1506089062880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.375333, 45.841833, -0.74 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926090", "mag": 1.6, "time": 1506088685970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.6016, 61.227, 75.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16877153", "mag": 1.3, "time": 1506088314826, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.7156, 61.5096, 6.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007840", "mag": 1.07, "time": 1506088185480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.7945, 33.498167, 6.09 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896831", "mag": 1.6, "time": 1506088032960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.772667, 38.806833, -0.28 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896826", "mag": 1.03, "time": 1506088021950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.822502, 38.836666, -0.75 ] } }, +{ "type": "Feature", "properties": { "id": "ak16877151", "mag": 1.7, "time": 1506087613938, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.3362, 62.1574, 11.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awqs", "mag": 4.3, "time": 1506087606500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 179.5624, -22.5585, 578.14 ] } }, +{ "type": "Feature", "properties": { "id": "ak16877148", "mag": 1.9, "time": 1506087297503, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.1731, 59.963, 87.7 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606565", "mag": 1.4, "time": 1506087185810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.2162, 38.2627, 3.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at3c", "mag": 4.4, "time": 1506086932700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 127.2264, -0.3969, 83.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at3j", "mag": 4.5, "time": 1506086850810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.4418, -19.1856, 573.86 ] } }, +{ "type": "Feature", "properties": { "id": "ak16877147", "mag": 1.0, "time": 1506086078366, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0434, 64.7457, 4.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876989", "mag": 2.3, "time": 1506085118552, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.6021, 60.5947, 0.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896781", "mag": 1.59, "time": 1506084858350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.773167, 38.807167, -0.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926084", "mag": 2.4, "time": 1506084692420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 178.7372, 51.5859, 56.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896771", "mag": 1.74, "time": 1506084487230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.771667, 38.808833, 0.14 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876986", "mag": 1.4, "time": 1506084219307, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.7611, 61.5102, 5.3 ] } }, +{ "type": "Feature", "properties": { "id": "hv61916896", "mag": 1.74, "time": 1506083571850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.465667, 19.190833, 35.257 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007816", "mag": 1.33, "time": 1506082333690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.362833, 33.373333, 6.28 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876984", "mag": 1.5, "time": 1506082188790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.7152, 61.5125, 7.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876981", "mag": 1.8, "time": 1506082118329, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.7017, 61.5113, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876980", "mag": 2.2, "time": 1506081950238, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.1633, 59.909, 114.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007792", "mag": 1.19, "time": 1506081499660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.503333, 35.304167, 5.36 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876977", "mag": 1.9, "time": 1506081250212, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.1121, 59.2751, 8.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876978", "mag": 1.2, "time": 1506081151639, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.9729, 61.6318, 32.9 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257019", "mag": 1.05, "time": 1506080783790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.526167, 46.879833, 10.93 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896746", "mag": 1.05, "time": 1506079850700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.73983, 38.763668, 1.53 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896741", "mag": 1.1, "time": 1506078851480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.806, 38.8165, 3.19 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248647", "mag": 1.45, "time": 1506078497740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.445, 42.561833, 8.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926075", "mag": 1.9, "time": 1506078386128, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.8777, 58.9992, 112.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876823", "mag": 1.1, "time": 1506078261719, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.8636, 62.788, 13.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876821", "mag": 1.4, "time": 1506077123303, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.923, 64.7739, 2.3 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606454", "mag": 2.6, "time": 1506077002610, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.5007, 36.7388, 7.5 ] } }, +{ "type": "Feature", "properties": { "id": "mb80257004", "mag": 1.43, "time": 1506075410640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5235, 46.871, 11.97 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896721", "mag": 1.39, "time": 1506074864460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.841333, 38.844167, 1.9 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606522", "mag": 1.1, "time": 1506074180637, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8235, 38.8303, 13.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007728", "mag": 1.52, "time": 1506073924220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.848, 36.181833, 2.23 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926070", "mag": 1.6, "time": 1506073391784, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -144.2241, 61.5539, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876665", "mag": 1.6, "time": 1506072332786, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.3288, 63.1852, 90.1 ] } }, +{ "type": "Feature", "properties": { "id": "hv61916851", "mag": 2.09, "time": 1506072148400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.868333, 20.063333, 23.409 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876664", "mag": 1.4, "time": 1506072136495, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.5912, 61.9919, 28.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926067", "mag": 1.3, "time": 1506071322182, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.632, 62.4195, 64.2 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248637", "mag": 1.3, "time": 1506070695930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.437167, 42.637667, 5.25 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at26", "mag": 4.5, "time": 1506070497460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 127.9846, 3.8293, 107.48 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926066", "mag": 1.6, "time": 1506069293924, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.7084, 58.832, 2.4 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248632", "mag": 2.03, "time": 1506068604640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -108.901833, 38.286167, 1.02 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876662", "mag": 1.9, "time": 1506067828515, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4502, 59.8034, 55.7 ] } }, +{ "type": "Feature", "properties": { "id": "nm60044913", "mag": 2.21, "time": 1506067533090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -92.239, 35.7905, 11.33 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876658", "mag": 3.5, "time": 1506066694779, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -159.9518, 54.8173, 3.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896676", "mag": 1.45, "time": 1506066561830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.764833, 38.786167, 0.53 ] } }, +{ "type": "Feature", "properties": { "id": "uw61309412", "mag": 1.49, "time": 1506066402670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -124.402833, 49.2735, 17.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896671", "mag": 1.2, "time": 1506066223530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8225, 37.524667, 2.51 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876647", "mag": 1.9, "time": 1506065065953, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.1147, 59.229, 11.0 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248627", "mag": 1.79, "time": 1506064954410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.417833, 42.575667, 8.31 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876640", "mag": 1.0, "time": 1506063798789, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.9184, 63.4232, 6.1 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256994", "mag": 1.71, "time": 1506063538810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.338833, 46.125333, 6.03 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at1d", "mag": 4.4, "time": 1506062755300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 151.9837, 45.5973, 22.46 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606510", "mag": 1.0, "time": 1506062740733, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9097, 38.416, 7.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876497", "mag": 2.9, "time": 1506062332060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -158.4396, 55.4155, 7.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876499", "mag": 1.5, "time": 1506062314773, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1276, 62.6705, 84.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926058", "mag": 2.5, "time": 1506062164434, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -163.9814, 52.5733, 21.3 ] } }, +{ "type": "Feature", "properties": { "id": "hv61916751", "mag": 1.88, "time": 1506061487210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.4615, 19.287167, 7.924 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926055", "mag": 2.4, "time": 1506060569450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.4546, 56.5041, 6.6 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248622", "mag": 1.34, "time": 1506060334660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.447833, 42.622833, 5.33 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606434", "mag": 1.2, "time": 1506060248714, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8235, 38.8296, 13.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007696", "mag": 1.17, "time": 1506059325210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.648333, 35.934, 3.86 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007680", "mag": 1.8, "time": 1506058671480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.570833, 35.360833, 4.84 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at0m", "mag": 5.5, "time": 1506058424310, "felt": 37, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -108.7724, 23.5614, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at0v", "mag": 4.5, "time": 1506056644580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 159.4959, 54.788, 131.21 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256984", "mag": 1.12, "time": 1506056537920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5285, 46.885167, 14.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926054", "mag": 1.3, "time": 1506056097918, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.7519, 60.0539, 56.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876343", "mag": 1.1, "time": 1506055943779, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.827, 62.7929, 14.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896616", "mag": 2.0, "time": 1506055463630, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.788667, 37.456333, 7.66 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926049", "mag": 2.0, "time": 1506055458648, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.9681, 59.782, 98.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at08", "mag": 4.7, "time": 1506054886300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -11.1483, -6.3489, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896606", "mag": 0.97, "time": 1506054333450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.821833, 37.5205, 2.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aszw", "mag": 4.2, "time": 1506054023580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 26.2553, 39.1304, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896586", "mag": 1.98, "time": 1506053997570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.883167, 37.538333, 2.49 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007648", "mag": 1.64, "time": 1506053954570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.797167, 33.495167, 4.61 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896591", "mag": 1.12, "time": 1506053943320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.789333, 37.455, 7.99 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aszh", "mag": 2.9, "time": 1506053328020, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -96.682, 35.846, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876210", "mag": 1.2, "time": 1506052567199, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.7614, 63.1414, 9.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876208", "mag": 1.0, "time": 1506051888104, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3642, 64.8396, 21.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876202", "mag": 2.8, "time": 1506051238210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.6975, 59.8426, 2.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007640", "mag": 1.04, "time": 1506050700240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.074333, 32.868, 9.32 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876199", "mag": 1.6, "time": 1506050508752, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.1502, 60.9709, 20.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876069", "mag": 1.7, "time": 1506048854655, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6692, 62.5598, 11.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16876067", "mag": 2.1, "time": 1506048427026, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.7111, 59.884, 14.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896561", "mag": 1.78, "time": 1506048332800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.779667, 37.392333, -2.31 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896556", "mag": 1.29, "time": 1506047940540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.0265, 36.559833, 6.76 ] } }, +{ "type": "Feature", "properties": { "id": "ak16926041", "mag": 2.5, "time": 1506047556201, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.992, 51.8656, 16.5 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248522", "mag": 1.34, "time": 1506047158170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.026833, 44.7755, 7.13 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256979", "mag": 1.73, "time": 1506043831850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.558333, 46.402, 3.35 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896531", "mag": 1.92, "time": 1506043357560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.780833, 37.389167, -2.29 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256969", "mag": 2.09, "time": 1506042441670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.930333, 44.292833, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875940", "mag": 1.1, "time": 1506041862266, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0885, 63.2553, 2.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awqf", "mag": 4.2, "time": 1506041406940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 165.3116, -15.6295, 57.06 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asyh", "mag": 4.6, "time": 1506041280550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 149.2095, 43.8815, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70235693", "mag": 1.82, "time": 1506040783670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.6825, 37.184, 4.37 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007600", "mag": 2.86, "time": 1506040660680, "felt": 13, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.171833, 34.730667, 1.72 ] } }, +{ "type": "Feature", "properties": { "id": "hv61916496", "mag": 1.7, "time": 1506040069030, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.755667, 19.862667, 13.433 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awqd", "mag": 4.6, "time": 1506040066970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 90.3605, 2.1475, 15.02 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875841", "mag": 1.4, "time": 1506039676822, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.7004, 63.8605, 6.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000atbx", "mag": 2.6, "time": 1506039659260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5671, 46.8969, 11.48 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avmv", "mag": 2.8, "time": 1506039531410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.0769, 52.3761, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256959", "mag": 1.07, "time": 1506038377030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.445667, 43.5435, 11.24 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007584", "mag": 1.19, "time": 1506037977370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.764667, 33.324167, 13.64 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875834", "mag": 1.4, "time": 1506037872803, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.518, 61.5639, 31.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896516", "mag": 1.31, "time": 1506037721390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.669, 37.2905, 3.04 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256954", "mag": 1.13, "time": 1506037549780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.4995, 46.8705, 10.41 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awq8", "mag": 4.4, "time": 1506037384370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 144.5809, 38.0785, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875828", "mag": 2.4, "time": 1506037110228, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.8706, 62.7902, 14.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875826", "mag": 1.7, "time": 1506036232042, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.4937, 61.5906, 31.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asx4", "mag": 2.7, "time": 1506036218800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.5127, 36.2915, 7.461 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007544", "mag": 3.0, "time": 1506035447270, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.397167, 32.383, 12.07 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007552", "mag": 1.61, "time": 1506035381320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.115667, 34.625667, -1.28 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875823", "mag": 1.6, "time": 1506035182231, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.5062, 64.6747, 9.2 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248487", "mag": 2.1, "time": 1506035003920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.420167, 42.525833, 7.93 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256939", "mag": 1.72, "time": 1506034952670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5215, 46.8665, 11.26 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875817", "mag": 1.5, "time": 1506034226408, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -167.0329, 53.5528, 17.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awq7", "mag": 4.3, "time": 1506034167940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -179.929, -23.7349, 550.89 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896506", "mag": 1.29, "time": 1506033952800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.821, 38.814833, 2.36 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875815", "mag": 1.5, "time": 1506033878487, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.5575, 60.0344, 58.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875810", "mag": 1.2, "time": 1506033325458, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.4889, 59.8624, 47.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875800", "mag": 1.4, "time": 1506032434891, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.7482, 66.977, 12.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875653", "mag": 4.2, "time": 1506032120973, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.8756, 62.7831, 20.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896496", "mag": 1.85, "time": 1506031741740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.5285, 36.803333, 3.27 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896486", "mag": 1.45, "time": 1506031445490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.526667, 36.809667, 4.3 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256934", "mag": 2.12, "time": 1506031400210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.9225, 44.303333, 10.34 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256929", "mag": 1.26, "time": 1506030770930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.747833, 45.079167, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007528", "mag": 1.87, "time": 1506030349230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.650167, 35.935333, 2.69 ] } }, +{ "type": "Feature", "properties": { "id": "hv61916321", "mag": 2.02, "time": 1506029779130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.552333, 19.137667, 49.513 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007520", "mag": 1.21, "time": 1506029730430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.157, 33.634167, -0.52 ] } }, +{ "type": "Feature", "properties": { "id": "hv61916316", "mag": 1.88, "time": 1506029586250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.419833, 19.099167, 42.057 ] } }, +{ "type": "Feature", "properties": { "id": "hv61916311", "mag": 1.76, "time": 1506029522880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.437167, 19.160333, 37.287 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606376", "mag": 1.1, "time": 1506029276288, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.9551, 40.0739, 10.9 ] } }, +{ "type": "Feature", "properties": { "id": "hv61916301", "mag": 1.85, "time": 1506029141190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.439167, 19.1175, 39.677 ] } }, +{ "type": "Feature", "properties": { "id": "ci37166108", "mag": 1.81, "time": 1506028904370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.241667, 32.920333, 11.27 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007512", "mag": 1.83, "time": 1506028897230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.241167, 32.916667, 7.87 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875651", "mag": 1.4, "time": 1506028324426, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.8843, 61.2141, 1.8 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606357", "mag": 2.6, "time": 1506028168100, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.6985, 39.7645, 7.3 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606355", "mag": 1.1, "time": 1506027762688, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.189, 38.4602, 2.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007480", "mag": 1.75, "time": 1506026384090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.371167, 35.054, 8.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875645", "mag": 1.7, "time": 1506026360117, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.75, 60.0811, 100.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896461", "mag": 1.53, "time": 1506026136260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.827333, 38.841167, 1.96 ] } }, +{ "type": "Feature", "properties": { "id": "ak16911613", "mag": 1.9, "time": 1506025569386, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.0904, 58.6739, 124.2 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70235678", "mag": 2.5, "time": 1506025487250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.888333, 37.204167, 6.25 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007472", "mag": 1.24, "time": 1506025368620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.488667, 33.850333, -0.48 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ass7", "mag": 4.8, "time": 1506025352080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.8962, 15.2536, 65.44 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007464", "mag": 1.18, "time": 1506025134310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.882167, 33.977333, 19.48 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875518", "mag": 1.7, "time": 1506024448536, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.5203, 61.3055, 10.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asr5", "mag": 2.8, "time": 1506024284460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4191, 42.5686, 11.52 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007448", "mag": 1.54, "time": 1506024073190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.493667, 33.846667, -0.48 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asqw", "mag": 4.5, "time": 1506023938000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -69.359, -24.593, 89.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896441", "mag": 0.97, "time": 1506023932370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.818337, 38.807335, 2.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16911611", "mag": 2.0, "time": 1506023546957, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -163.8314, 53.8887, 16.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875513", "mag": 2.1, "time": 1506022669821, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.6752, 67.929, 13.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875511", "mag": 1.6, "time": 1506022479067, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0122, 60.6265, 55.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896431", "mag": 1.59, "time": 1506022296440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.821333, 37.606, 4.18 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asq8", "mag": 4.5, "time": 1506022120080, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 57.3957, 30.689, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875508", "mag": 2.8, "time": 1506022088454, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.5339, 56.4471, 34.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875497", "mag": 2.8, "time": 1506021225649, "felt": 5, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.3633, 62.2263, 8.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875489", "mag": 2.0, "time": 1506019153622, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.5458, 60.2285, 104.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007432", "mag": 0.97, "time": 1506018755920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.4305, 33.027167, 7.61 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896416", "mag": 1.32, "time": 1506018676310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.105167, 37.325333, -0.31 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875470", "mag": 3.4, "time": 1506018115237, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3313, 62.0747, 82.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007408", "mag": 1.52, "time": 1506017937430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.240833, 33.339, 3.36 ] } }, +{ "type": "Feature", "properties": { "id": "ci37165948", "mag": 1.22, "time": 1506017934430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.238, 33.341, 5.25 ] } }, +{ "type": "Feature", "properties": { "id": "ak16911603", "mag": 2.2, "time": 1506016859139, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.198, 56.7455, 55.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896411", "mag": 1.56, "time": 1506016054120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.955667, 36.390833, 1.45 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ask8", "mag": 5.2, "time": 1506015812780, "felt": 1, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 153.792, -5.2273, 42.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875367", "mag": 1.0, "time": 1506015790628, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.3293, 61.4367, 9.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896401", "mag": 1.29, "time": 1506015349390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.136833, 36.591, 7.95 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896396", "mag": 1.65, "time": 1506015154000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.830667, 38.841833, 1.92 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875364", "mag": 1.7, "time": 1506014707392, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.9511, 61.182, 6.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asjm", "mag": 4.1, "time": 1506014582020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.1412, 14.9651, 31.77 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896391", "mag": 1.65, "time": 1506014547620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.522667, 37.119333, 6.68 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896386", "mag": 2.74, "time": 1506013969600, "felt": 15, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.523, 37.119333, 7.11 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248457", "mag": 1.24, "time": 1506013292240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.416833, 42.5455, 6.54 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896381", "mag": 1.42, "time": 1506013025480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.7985, 38.024167, 4.23 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875337", "mag": 1.5, "time": 1506012889205, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.8562, 59.8876, 14.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875335", "mag": 1.5, "time": 1506012588856, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -142.43, 69.5255, 6.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875333", "mag": 1.4, "time": 1506012078477, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -144.7448, 65.4677, 16.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asj3", "mag": 4.4, "time": 1506011673160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 94.8925, 24.9992, 82.35 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875233", "mag": 2.0, "time": 1506011166366, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.0389, 62.6945, 1.1 ] } }, +{ "type": "Feature", "properties": { "id": "hv61916021", "mag": 1.65, "time": 1506010758380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.606333, 19.988, 0.02 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896356", "mag": 1.08, "time": 1506008853280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.736, 38.789501, 1.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007344", "mag": 1.64, "time": 1506006904290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.040833, 34.932167, 7.95 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248432", "mag": 1.93, "time": 1506005934630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -108.899167, 38.2825, 1.23 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896351", "mag": 1.05, "time": 1506005402280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.872833, 37.542167, 5.65 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875225", "mag": 2.6, "time": 1506004864279, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.7558, 56.7802, 85.5 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606271", "mag": 1.4, "time": 1506004765898, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9071, 38.404, 8.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16911592", "mag": 1.8, "time": 1506004687871, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.776, 59.9457, 96.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875224", "mag": 1.0, "time": 1506004284441, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.1472, 58.225, 2.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asgp", "mag": 3.1, "time": 1506004160400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4287, 42.5341, 7.73 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875128", "mag": 1.2, "time": 1506003424957, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.1414, 61.9718, 7.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875123", "mag": 2.2, "time": 1506003380008, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.406, 61.1636, 56.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875122", "mag": 1.5, "time": 1506003168025, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.6121, 60.6288, 27.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asgl", "mag": 4.5, "time": 1506003018350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 150.7163, -5.3996, 143.64 ] } }, +{ "type": "Feature", "properties": { "id": "ak16911587", "mag": 2.0, "time": 1506002992795, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -161.2107, 54.658, 25.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875121", "mag": 1.3, "time": 1506002287075, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7877, 63.0935, 115.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875120", "mag": 1.3, "time": 1506002190951, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.3702, 60.2093, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896346", "mag": 1.58, "time": 1506001285170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.046, 37.631, -2.49 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875118", "mag": 1.5, "time": 1506001054310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4947, 65.9329, 9.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875115", "mag": 1.2, "time": 1506000273641, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.8273, 59.8914, 16.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875114", "mag": 1.0, "time": 1505999744527, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.927, 63.1123, 88.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875113", "mag": 1.0, "time": 1505999509220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.8959, 53.8648, 4.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896326", "mag": 1.49, "time": 1505998900750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.040833, 37.6325, -1.69 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896316", "mag": 1.09, "time": 1505998199150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.854333, 37.553667, -1.13 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896306", "mag": 1.43, "time": 1505997631810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.009333, 37.578833, 2.18 ] } }, +{ "type": "Feature", "properties": { "id": "nm60207176", "mag": 1.81, "time": 1505997033100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -89.530833, 36.304833, 9.49 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875021", "mag": 1.2, "time": 1505996145934, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.8383, 65.938, 13.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875018", "mag": 1.2, "time": 1505995669198, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.912, 65.5133, 9.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896296", "mag": 1.47, "time": 1505995317350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.196833, 37.9145, 9.67 ] } }, +{ "type": "Feature", "properties": { "id": "nm60207166", "mag": 1.64, "time": 1505994488630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -89.4975, 36.289667, 7.47 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asex", "mag": 4.8, "time": 1505994269370, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.2903, 15.7805, 100.11 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606244", "mag": 1.4, "time": 1505993181062, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.2534, 40.7726, 2.5 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248402", "mag": 1.76, "time": 1505993050130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.834, 37.5, 12.34 ] } }, +{ "type": "Feature", "properties": { "id": "ak16911577", "mag": 1.8, "time": 1505992688210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.7102, 59.2193, 101.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896276", "mag": 1.87, "time": 1505990638730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.821833, 38.807833, 2.57 ] } }, +{ "type": "Feature", "properties": { "id": "ak16911575", "mag": 1.4, "time": 1505990312220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.1289, 60.9457, 91.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007296", "mag": 1.16, "time": 1505989019560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.893333, 33.8875, 12.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874826", "mag": 2.4, "time": 1505988598717, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.0672, 60.3368, 3.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874821", "mag": 3.9, "time": 1505988559362, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.0266, 58.0197, 4.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asdx", "mag": 3.2, "time": 1505987188740, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4339, 42.5809, 9.51 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896231", "mag": 1.31, "time": 1505985984190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7595, 39.290333, 11.74 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874817", "mag": 1.2, "time": 1505985541058, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7623, 63.2246, 123.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896221", "mag": 1.81, "time": 1505985066080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8215, 37.605333, 4.11 ] } }, +{ "type": "Feature", "properties": { "id": "ak16911571", "mag": 1.2, "time": 1505984945428, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6774, 60.3679, 51.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000astb", "mag": 3.2, "time": 1505984479950, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 30.4877, 39.7496, 7.26 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874735", "mag": 1.1, "time": 1505984351439, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1345, 61.0202, 12.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874733", "mag": 1.8, "time": 1505984244290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -144.6331, 69.6221, 10.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16911567", "mag": 1.4, "time": 1505983878943, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.6066, 58.3406, 70.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874730", "mag": 1.6, "time": 1505983557544, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6496, 63.2391, 128.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874715", "mag": 3.0, "time": 1505983090867, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.9585, 60.2394, 134.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874713", "mag": 1.8, "time": 1505982752561, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3398, 60.0395, 62.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874708", "mag": 1.6, "time": 1505981986749, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.5434, 62.0196, 9.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007280", "mag": 1.01, "time": 1505981662400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.966, 33.952667, 12.57 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896186", "mag": 1.8, "time": 1505981520300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.764333, 38.786167, 0.23 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874635", "mag": 1.2, "time": 1505980470681, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.9567, 61.1836, 3.9 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256854", "mag": 1.19, "time": 1505980355400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.540333, 46.865833, 13.58 ] } }, +{ "type": "Feature", "properties": { "id": "hv61915846", "mag": 2.23, "time": 1505980220010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.471833, 19.187167, 6.497 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896176", "mag": 1.82, "time": 1505979900900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.789167, 37.455, 8.23 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874613", "mag": 2.5, "time": 1505979347188, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.6995, 61.302, 18.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896141", "mag": 1.44, "time": 1505978529860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.0545, 37.976333, 16.99 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asd1", "mag": 4.8, "time": 1505977959710, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -73.683, -37.9104, 6.87 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896116", "mag": 1.08, "time": 1505977815960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.784164, 38.838165, 0.65 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007272", "mag": 1.44, "time": 1505977166870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.235667, 34.473, 10.66 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874540", "mag": 1.8, "time": 1505976691446, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.5178, 59.5615, 114.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007264", "mag": 1.35, "time": 1505976496140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.8585, 33.885833, 13.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874539", "mag": 1.4, "time": 1505975897075, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.7553, 60.3904, 17.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16911557", "mag": 1.9, "time": 1505975896384, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.7415, 56.6876, 60.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874533", "mag": 2.4, "time": 1505975550653, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -160.4341, 54.7916, 41.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874531", "mag": 1.6, "time": 1505973877209, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0439, 60.1347, 121.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896081", "mag": 0.98, "time": 1505973711190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.775002, 38.797669, 2.77 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896076", "mag": 2.49, "time": 1505973410410, "felt": 16, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.785833, 37.46, 8.35 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874465", "mag": 1.3, "time": 1505973344875, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -138.0133, 60.1082, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16911553", "mag": 1.4, "time": 1505972962694, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3138, 59.699, 53.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16911552", "mag": 1.2, "time": 1505972745844, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4845, 60.1615, 61.1 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606219", "mag": 1.3, "time": 1505972571887, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.1193, 38.2806, 9.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16911551", "mag": 1.8, "time": 1505972563999, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.15, 51.5531, 43.8 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606295", "mag": 1.0, "time": 1505972403264, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.6227, 38.8065, 14.1 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248342", "mag": 1.16, "time": 1505971839680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.427333, 42.584333, 6.41 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874458", "mag": 1.0, "time": 1505971795387, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.1789, 60.7931, 15.4 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606215", "mag": 1.1, "time": 1505970724921, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9138, 38.4144, 3.9 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606292", "mag": 1.2, "time": 1505969821916, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9096, 38.3591, 10.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874386", "mag": 2.2, "time": 1505966674333, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.1806, 62.1688, 58.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874381", "mag": 1.5, "time": 1505966192127, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -158.3423, 67.4818, 11.5 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606289", "mag": 1.1, "time": 1505965897622, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.612, 39.7777, 13.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874378", "mag": 1.4, "time": 1505965635289, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.6084, 59.8249, 2.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007240", "mag": 1.33, "time": 1505964848260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.392833, 34.0695, 3.63 ] } }, +{ "type": "Feature", "properties": { "id": "uw61309117", "mag": 1.41, "time": 1505964727680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.537333, 45.623, 3.45 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asac", "mag": 2.3, "time": 1505963189900, "felt": 8, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.6319, 35.02, 3.66 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896016", "mag": 1.0, "time": 1505962244660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.777664, 38.821335, 1.62 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874313", "mag": 1.6, "time": 1505961692924, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.4015, 58.981, 9.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896006", "mag": 2.63, "time": 1505961234600, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.778, 38.822333, 1.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874294", "mag": 1.4, "time": 1505960998663, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.7592, 62.4966, 63.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16911541", "mag": 1.2, "time": 1505959763113, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.0959, 69.101, 9.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72896001", "mag": 2.06, "time": 1505958864360, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.541, 35.984333, 10.27 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007216", "mag": 1.05, "time": 1505958019680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.250167, 34.038167, 14.18 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874254", "mag": 3.1, "time": 1505957941327, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 178.4863, 51.2677, 13.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874229", "mag": 1.1, "time": 1505957058757, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.7027, 61.7499, 26.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874215", "mag": 1.1, "time": 1505956445202, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.6955, 63.1111, 9.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007208", "mag": 1.4, "time": 1505955985550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.416, 33.868667, 14.65 ] } }, +{ "type": "Feature", "properties": { "id": "hv61915531", "mag": 1.72, "time": 1505955195430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.279833, 19.405667, 1.328 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874182", "mag": 2.0, "time": 1505954859125, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.6742, 63.0988, 11.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000as95", "mag": 4.5, "time": 1505954623610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.9506, -18.3191, 525.15 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874180", "mag": 1.0, "time": 1505954368489, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.6875, 63.1114, 10.6 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256829", "mag": 1.22, "time": 1505954178230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.729167, 46.9255, 15.18 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007192", "mag": 2.27, "time": 1505953985850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.389333, 34.875667, 4.87 ] } }, +{ "type": "Feature", "properties": { "id": "ak16911531", "mag": 3.1, "time": 1505953036619, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.8238, 52.2316, 212.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874133", "mag": 1.9, "time": 1505952707526, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.3476, 61.7239, 1.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895971", "mag": 2.7, "time": 1505952459520, "felt": 25, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.065833, 37.977333, 16.12 ] } }, +{ "type": "Feature", "properties": { "id": "us2000as7z", "mag": 5.0, "time": 1505952320920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -175.3417, -18.3348, 223.14 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874122", "mag": 1.3, "time": 1505952267890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -161.1071, 68.0646, 14.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874119", "mag": 1.3, "time": 1505952216610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9186, 60.9563, 9.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000as7r", "mag": 5.7, "time": 1505951964840, "felt": 7, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 113.0028, -6.141, 588.64 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007168", "mag": 1.0, "time": 1505951908320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.513, 33.929833, 3.12 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874078", "mag": 1.5, "time": 1505949607121, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.307, 64.9865, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895936", "mag": 2.34, "time": 1505948330470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.830833, 38.8385, 2.22 ] } }, +{ "type": "Feature", "properties": { "id": "us2000as71", "mag": 4.4, "time": 1505948258880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -70.8955, -19.9851, 13.88 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007144", "mag": 2.26, "time": 1505947525530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.600667, 32.8185, 11.77 ] } }, +{ "type": "Feature", "properties": { "id": "us2000as6n", "mag": 4.7, "time": 1505946967130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 148.002, -5.1396, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16874025", "mag": 1.8, "time": 1505946583777, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5728, 63.1811, 118.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000as5y", "mag": 5.2, "time": 1505945844590, "felt": null, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 147.9821, -5.1384, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000as5x", "mag": 5.9, "time": 1505945616140, "felt": null, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 147.8337, -5.11, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873995", "mag": 1.3, "time": 1505944353830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.7194, 63.0772, 10.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895916", "mag": 1.33, "time": 1505944123270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8235, 37.532, 3.23 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903715", "mag": 1.5, "time": 1505944050318, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.7597, 60.286, 105.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873983", "mag": 1.6, "time": 1505944038560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.2822, 60.1956, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873980", "mag": 1.5, "time": 1505943645116, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.7128, 62.2758, 1.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895911", "mag": 1.05, "time": 1505943458060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.817497, 38.818165, 1.98 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256764", "mag": 1.19, "time": 1505942553810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.3355, 46.855167, 12.51 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873969", "mag": 1.0, "time": 1505941809382, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.8648, 61.3084, 14.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903709", "mag": 1.3, "time": 1505940388991, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.1675, 59.8496, 11.5 ] } }, +{ "type": "Feature", "properties": { "id": "hv61915241", "mag": 2.0, "time": 1505940250470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.695496, 19.176666, 1.78 ] } }, +{ "type": "Feature", "properties": { "id": "uw61309057", "mag": 2.31, "time": 1505940000150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.92, 47.376, -0.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873814", "mag": 1.4, "time": 1505938885178, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.4385, 61.7606, 10.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873808", "mag": 1.1, "time": 1505938683669, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.6592, 62.5852, 59.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895876", "mag": 1.45, "time": 1505938357840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.59, 36.021667, 3.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873804", "mag": 1.4, "time": 1505938263457, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.3926, 60.1466, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000as2f", "mag": 6.4, "time": 1505938189810, "felt": 16, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 169.0947, -18.7978, 200.19 ] } }, +{ "type": "Feature", "properties": { "id": "hv61915206", "mag": 2.51, "time": 1505938077390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.033667, 19.2375, 39.578 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007104", "mag": 1.0, "time": 1505937649230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.0765, 32.813833, -0.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873801", "mag": 2.0, "time": 1505937512139, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.8359, 53.871, 5.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000as1w", "mag": 2.5, "time": 1505937361300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.0579, 36.6187, 5.828 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873782", "mag": 1.2, "time": 1505936869830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.8873, 62.1092, 41.4 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256709", "mag": 1.79, "time": 1505935321500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.451, 43.543667, 10.41 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606121", "mag": 1.5, "time": 1505934916827, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.1139, 37.3666, 2.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007096", "mag": 1.15, "time": 1505934203280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.751, 34.839333, -1.28 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606180", "mag": 1.3, "time": 1505934149532, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.1164, 38.3161, 11.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895851", "mag": 1.27, "time": 1505934073910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.592833, 39.610333, 2.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873739", "mag": 2.2, "time": 1505933777306, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.4033, 69.0735, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873736", "mag": 1.7, "time": 1505933267549, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.2132, 61.1317, 38.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007072", "mag": 2.71, "time": 1505931747440, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.389167, 32.380167, 15.18 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895826", "mag": 1.69, "time": 1505931012940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.428333, 36.582667, 0.68 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248192", "mag": 1.44, "time": 1505930780280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.474333, 42.6455, 0.08 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895816", "mag": 2.1, "time": 1505929719570, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.9675, 40.890167, 14.69 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873728", "mag": 1.2, "time": 1505929479491, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.582, 62.6618, 78.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873142", "mag": 1.5, "time": 1505927860541, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2216, 61.5685, 73.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895806", "mag": 3.65, "time": 1505927408630, "felt": 119, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.983667, 40.891333, 16.86 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895796", "mag": 3.18, "time": 1505926479240, "felt": 56, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.546833, 36.829167, 3.48 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873012", "mag": 1.4, "time": 1505926389012, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.6968, 59.7895, 4.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arxv", "mag": 6.1, "time": 1505925436360, "felt": 102, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 144.6601, 37.9814, 11.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16872904", "mag": 1.0, "time": 1505925010295, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.5787, 62.1577, 21.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arxl", "mag": 5.3, "time": 1505924711310, "felt": null, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 118.8822, -10.1961, 10.84 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arxs", "mag": 4.4, "time": 1505923365600, "felt": 13, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 135.4357, 33.9578, 44.93 ] } }, +{ "type": "Feature", "properties": { "id": "ak16872233", "mag": 1.2, "time": 1505923328725, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.1746, 60.1861, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007024", "mag": 0.95, "time": 1505922246000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.593333, 34.202833, 4.57 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arwt", "mag": 4.9, "time": 1505921548830, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 166.9265, -14.913, 39.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arwd", "mag": 2.4, "time": 1505921250610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.783, 37.3255, 5.27 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awnu", "mag": 4.6, "time": 1505921168060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -28.7481, 43.6321, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248182", "mag": 1.14, "time": 1505920908550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.455667, 42.606, 5.92 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arw1", "mag": 4.4, "time": 1505920105280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 70.9001, 36.5943, 194.83 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awp1", "mag": 4.1, "time": 1505919984040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -82.8639, 5.1272, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903689", "mag": 2.1, "time": 1505918855154, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.5285, 56.3302, 52.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16871415", "mag": 1.5, "time": 1505918684626, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.5508, 61.18, 5.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arvu", "mag": 5.0, "time": 1505918528120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.1207, -17.9346, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38007016", "mag": 1.44, "time": 1505918468750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.514, 33.93, 3.08 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895731", "mag": 2.2, "time": 1505918095770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -124.179, 40.2545, 10.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arvi", "mag": 5.3, "time": 1505917796770, "felt": 41, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 121.7572, 23.2931, 22.03 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895726", "mag": 2.76, "time": 1505917745400, "felt": 8, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -124.182833, 40.246333, 11.38 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248172", "mag": 2.13, "time": 1505916637780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4155, 42.592833, 6.06 ] } }, +{ "type": "Feature", "properties": { "id": "ak16870720", "mag": 2.0, "time": 1505915942888, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.6193, 67.4066, 12.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16870653", "mag": 1.8, "time": 1505915336300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.2998, 61.7353, 47.3 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256619", "mag": 1.37, "time": 1505914951120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.527333, 46.886167, 13.87 ] } }, +{ "type": "Feature", "properties": { "id": "ci38006992", "mag": 1.47, "time": 1505914753140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.453667, 34.324833, 9.66 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895721", "mag": 2.38, "time": 1505913728570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.6465, 36.06, 20.18 ] } }, +{ "type": "Feature", "properties": { "id": "ci38006968", "mag": 1.06, "time": 1505913698350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.79, 36.101, 8.43 ] } }, +{ "type": "Feature", "properties": { "id": "ci38006952", "mag": 2.21, "time": 1505911740560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.197667, 32.419333, 10.66 ] } }, +{ "type": "Feature", "properties": { "id": "ak16869931", "mag": 1.0, "time": 1505911683814, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.0983, 64.9958, 11.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16869929", "mag": 1.1, "time": 1505910877864, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.9571, 64.0729, 125.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arkq", "mag": 5.0, "time": 1505910355700, "felt": 1, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 132.5848, 1.0854, 36.12 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248167", "mag": 1.05, "time": 1505910339650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.078167, 44.806167, 7.81 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arkf", "mag": 2.7, "time": 1505910255780, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4578, 42.6105, 7.92 ] } }, +{ "type": "Feature", "properties": { "id": "hv61914931", "mag": 1.25, "time": 1505910251630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.624833, 19.4175, 3.162 ] } }, +{ "type": "Feature", "properties": { "id": "ak16869355", "mag": 1.3, "time": 1505910194393, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.4867, 61.3624, 40.7 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248157", "mag": 1.62, "time": 1505909926720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.418333, 42.6315, 2.43 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606071", "mag": 1.9, "time": 1505909820104, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.6351, 40.2652, 7.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci38006936", "mag": 1.08, "time": 1505907735210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.542167, 33.157167, 16.18 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895696", "mag": 1.65, "time": 1505907470630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.887667, 39.9645, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248147", "mag": 1.97, "time": 1505907452270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.426833, 42.575667, 8.53 ] } }, +{ "type": "Feature", "properties": { "id": "hv61914886", "mag": 2.38, "time": 1505907343420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.275162, 19.410833, 10.08 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903676", "mag": 1.3, "time": 1505907050579, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.6927, 60.366, 14.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16869212", "mag": 1.1, "time": 1505906705387, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.0351, 61.9136, 37.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895691", "mag": 1.89, "time": 1505906617690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.802667, 36.023667, 14.48 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903672", "mag": 2.7, "time": 1505906309964, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.8205, 51.5611, 26.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895686", "mag": 1.58, "time": 1505906251960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.257833, 39.404167, 3.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16868636", "mag": 1.1, "time": 1505905797402, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.4101, 61.9294, 46.0 ] } }, +{ "type": "Feature", "properties": { "id": "nm60207096", "mag": 1.74, "time": 1505905515890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -89.502, 36.239333, 7.22 ] } }, +{ "type": "Feature", "properties": { "id": "ak16868555", "mag": 1.6, "time": 1505904607416, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.81, 59.8821, 7.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arj1", "mag": 4.7, "time": 1505903968940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.4191, 15.2723, 57.48 ] } }, +{ "type": "Feature", "properties": { "id": "ci38006912", "mag": 1.07, "time": 1505903473810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.495167, 35.975167, 6.03 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248142", "mag": 1.89, "time": 1505903157450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.424333, 42.560333, 7.63 ] } }, +{ "type": "Feature", "properties": { "id": "ak16868496", "mag": 2.0, "time": 1505903116550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.9125, 61.7794, 102.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16868494", "mag": 1.5, "time": 1505903092907, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.2214, 61.9475, 35.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903665", "mag": 1.3, "time": 1505902710790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.7292, 62.9468, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16867924", "mag": 1.2, "time": 1505902608214, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.7213, 59.8967, 2.1 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606156", "mag": 1.0, "time": 1505901862661, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.6593, 38.6914, 6.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895661", "mag": 1.05, "time": 1505901620810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.810837, 38.818668, 2.51 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903662", "mag": 1.0, "time": 1505901509250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.8825, 63.8483, 113.3 ] } }, +{ "type": "Feature", "properties": { "id": "hv61914831", "mag": 1.76, "time": 1505901369660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.477661, 19.182333, 34.15 ] } }, +{ "type": "Feature", "properties": { "id": "ak16867848", "mag": 1.1, "time": 1505900653451, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4004, 63.1493, 5.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arir", "mag": 3.7, "time": 1505900227020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -160.1086, 55.2931, 60.27 ] } }, +{ "type": "Feature", "properties": { "id": "uw61331666", "mag": 1.1, "time": 1505898593660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.672, 48.548667, -0.01 ] } }, +{ "type": "Feature", "properties": { "id": "ci38006880", "mag": 2.13, "time": 1505898547760, "felt": 137, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.512, 33.929167, 3.06 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arig", "mag": 4.9, "time": 1505898116470, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 141.0335, 30.5728, 51.74 ] } }, +{ "type": "Feature", "properties": { "id": "ak16867217", "mag": 1.6, "time": 1505898082784, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.4786, 59.9819, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16867146", "mag": 1.1, "time": 1505897266615, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -142.8777, 60.4396, 4.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci38006872", "mag": 1.46, "time": 1505897209710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.797667, 33.493667, 4.26 ] } }, +{ "type": "Feature", "properties": { "id": "ak16867139", "mag": 2.2, "time": 1505896599575, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3632, 62.9389, 110.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895641", "mag": 1.43, "time": 1505896494260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.840333, 37.569333, 1.25 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903656", "mag": 1.6, "time": 1505896455015, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.6591, 59.7355, 84.3 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248127", "mag": 1.21, "time": 1505896112670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.409833, 42.577333, 5.18 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248122", "mag": 1.04, "time": 1505896073990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.420167, 42.597, 5.54 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ari7", "mag": 2.8, "time": 1505895800120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4288, 42.5861, 7.69 ] } }, +{ "type": "Feature", "properties": { "id": "hv61914791", "mag": 2.56, "time": 1505895324160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.2775, 19.387833, 2.782 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248112", "mag": 2.6, "time": 1505895001440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.426333, 42.581333, 7.79 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903653", "mag": 1.4, "time": 1505894006715, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.1734, 57.6592, 5.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895626", "mag": 1.53, "time": 1505893505020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.731, 35.610333, 5.63 ] } }, +{ "type": "Feature", "properties": { "id": "ak16866448", "mag": 1.5, "time": 1505893091784, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2468, 62.4591, 77.3 ] } }, +{ "type": "Feature", "properties": { "id": "uu60013094", "mag": 1.81, "time": 1505893039830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.445667, 42.595833, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci38006824", "mag": 1.12, "time": 1505893038610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.764667, 36.027, 1.93 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248107", "mag": 1.76, "time": 1505893022850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.440667, 42.600667, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "hv61914781", "mag": 1.67, "time": 1505892711130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.6165, 19.4305, 3.542 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903651", "mag": 3.0, "time": 1505892680068, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -160.4523, 53.0789, 11.0 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248102", "mag": 1.36, "time": 1505892622540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.435667, 42.589167, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16866421", "mag": 1.6, "time": 1505892318030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3481, 59.8279, 3.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16866396", "mag": 2.2, "time": 1505891995067, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -162.4096, 54.4777, 11.3 ] } }, +{ "type": "Feature", "properties": { "id": "hv61914776", "mag": 1.93, "time": 1505891884110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.875167, 19.494, 13.771 ] } }, +{ "type": "Feature", "properties": { "id": "ak16866395", "mag": 1.1, "time": 1505891525159, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.5895, 59.7855, 1.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16865784", "mag": 1.7, "time": 1505890304255, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.8219, 63.9434, 110.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903645", "mag": 1.5, "time": 1505889690090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.8317, 59.5969, 83.3 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248092", "mag": 1.25, "time": 1505889314510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4045, 42.559, 7.09 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903644", "mag": 1.6, "time": 1505888156227, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.1233, 56.6112, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903642", "mag": 1.1, "time": 1505887874395, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.5943, 62.8332, 79.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arhc", "mag": 2.7, "time": 1505887339310, "felt": 5, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -96.7528, 35.56, 6.78 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606041", "mag": 1.5, "time": 1505886348191, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.1044, 37.3927, 2.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16865084", "mag": 2.3, "time": 1505886195952, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -142.96, 68.8119, 5.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16865080", "mag": 1.0, "time": 1505886128688, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -144.8653, 65.3778, 3.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16865073", "mag": 2.0, "time": 1505885821473, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.5664, 57.7913, 90.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16865048", "mag": 1.0, "time": 1505885371718, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.9661, 63.2402, 5.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arh1", "mag": 5.3, "time": 1505885168970, "felt": 29, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -71.3157, -16.2747, 92.59 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arha", "mag": 4.8, "time": 1505884561830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 148.9933, 44.304, 47.06 ] } }, +{ "type": "Feature", "properties": { "id": "ak16865027", "mag": 1.7, "time": 1505884405432, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.8016, 59.167, 62.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903636", "mag": 2.1, "time": 1505884147575, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -159.2848, 54.6322, 28.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16864392", "mag": 1.4, "time": 1505881969592, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.3599, 61.7927, 48.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606034", "mag": 1.2, "time": 1505881284660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8997, 38.3821, 8.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903634", "mag": 1.9, "time": 1505881021363, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.3362, 59.9873, 134.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16864345", "mag": 1.4, "time": 1505880564938, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.7317, 59.9227, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16864341", "mag": 1.9, "time": 1505880299039, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2295, 62.4633, 79.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903630", "mag": 1.6, "time": 1505878577379, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2105, 59.7151, 108.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci38006744", "mag": 1.15, "time": 1505878429650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.3295, 36.066833, 4.96 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248077", "mag": 1.22, "time": 1505878406660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.422667, 42.523667, 7.06 ] } }, +{ "type": "Feature", "properties": { "id": "ci38006752", "mag": 1.09, "time": 1505878374600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.328333, 36.063333, 2.53 ] } }, +{ "type": "Feature", "properties": { "id": "ak16863731", "mag": 2.4, "time": 1505878347669, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.1296, 60.1348, 9.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903628", "mag": 1.7, "time": 1505878317110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2703, 59.8732, 126.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16863732", "mag": 1.2, "time": 1505878286762, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.9406, 59.985, 1.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci38006736", "mag": 1.86, "time": 1505878275980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.331167, 36.0625, 4.96 ] } }, +{ "type": "Feature", "properties": { "id": "ci37165628", "mag": 1.61, "time": 1505878262700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.3305, 36.062833, 2.62 ] } }, +{ "type": "Feature", "properties": { "id": "ak16863728", "mag": 1.3, "time": 1505878130865, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3801, 60.7066, 4.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000argd", "mag": 4.6, "time": 1505878085370, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.8719, 16.1444, 48.73 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248072", "mag": 2.35, "time": 1505878084670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.423167, 42.581333, 8.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16863729", "mag": 2.5, "time": 1505878081761, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4258, 51.6886, 13.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895536", "mag": 1.94, "time": 1505877892960, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.286167, 36.776667, 10.03 ] } }, +{ "type": "Feature", "properties": { "id": "ci38006720", "mag": 1.07, "time": 1505877439420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.752, 33.713, 15.96 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248067", "mag": 1.47, "time": 1505877309800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.445, 42.617667, 6.11 ] } }, +{ "type": "Feature", "properties": { "id": "ci38006712", "mag": 1.07, "time": 1505875949770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.750333, 33.961833, 15.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awn6", "mag": 4.0, "time": 1505875623990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 179.7511, -25.3193, 527.05 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arfw", "mag": 4.9, "time": 1505875330110, "felt": 12, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 174.3444, -41.5073, 24.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arfs", "mag": 4.9, "time": 1505875055560, "felt": 8, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -90.9075, 14.5711, 178.93 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017263000", "mag": 2.75, "time": 1505873919890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -66.3401, 18.9298, 12.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16863060", "mag": 1.9, "time": 1505873560207, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.1132, 59.1631, 57.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895516", "mag": 1.58, "time": 1505873402400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.522667, 35.964833, 7.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arf6", "mag": 2.7, "time": 1505873292330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.6365, 59.7836, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arfq", "mag": 2.8, "time": 1505872583380, "felt": 5, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -2.1386, 37.4306, 7.84 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895506", "mag": 1.14, "time": 1505872092600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.103, 36.606333, 9.92 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arel", "mag": 6.1, "time": 1505871807940, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 162.614, -50.7145, 19.83 ] } }, +{ "type": "Feature", "properties": { "id": "ak16862483", "mag": 2.0, "time": 1505871449331, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.323, 61.0377, 13.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16862466", "mag": 1.1, "time": 1505870969313, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.0763, 60.3456, 0.4 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256529", "mag": 1.31, "time": 1505870488260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.528, 46.8965, 11.33 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895486", "mag": 1.47, "time": 1505870467130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.586, 36.020333, 4.08 ] } }, +{ "type": "Feature", "properties": { "id": "us2000are4", "mag": 4.5, "time": 1505868292650, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 141.5418, -3.912, 43.33 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248037", "mag": 2.04, "time": 1505868182810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.450167, 42.612833, 6.23 ] } }, +{ "type": "Feature", "properties": { "id": "uu60248032", "mag": 1.14, "time": 1505868031480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.415833, 42.508, 5.93 ] } }, +{ "type": "Feature", "properties": { "id": "us2000are1", "mag": 2.5, "time": 1505867820700, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.7971, 36.457, 5.777 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895456", "mag": 1.52, "time": 1505867731230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.668833, 37.291667, 4.46 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ardv", "mag": 5.0, "time": 1505866095740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 57.4066, 30.7208, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903617", "mag": 1.9, "time": 1505866055349, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.744, 56.8763, 33.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903616", "mag": 1.8, "time": 1505865710189, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -159.5947, 55.8757, 101.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16903615", "mag": 1.8, "time": 1505865589920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0266, 60.2087, 122.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ass3", "mag": 2.5, "time": 1505864736500, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.8008, 36.4519, 6.233 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256499", "mag": 1.38, "time": 1505864394760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.407833, 45.589, 4.43 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arcp", "mag": 3.0, "time": 1505863612870, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4223, 42.5909, 9.63 ] } }, +{ "type": "Feature", "properties": { "id": "uw61331476", "mag": 1.93, "time": 1505863558820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.772333, 46.652333, -0.79 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arcv", "mag": 4.6, "time": 1505863376420, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 123.9102, 6.3611, 38.14 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arck", "mag": 2.6, "time": 1505863101700, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.9891, 36.9623, 5.329 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arch", "mag": 4.6, "time": 1505862692240, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.8625, 16.2348, 45.26 ] } }, +{ "type": "Feature", "properties": { "id": "uw61331461", "mag": 1.43, "time": 1505862649350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.194333, 46.983167, -0.67 ] } }, +{ "type": "Feature", "properties": { "id": "ak16861101", "mag": 1.0, "time": 1505862438423, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3714, 64.9781, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arca", "mag": 4.7, "time": 1505862303600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 179.4478, -36.2513, 47.77 ] } }, +{ "type": "Feature", "properties": { "id": "ak16860573", "mag": 1.3, "time": 1505861271657, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6706, 62.0713, 0.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arbk", "mag": 2.4, "time": 1505861097180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4595, 42.608, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aray", "mag": 3.2, "time": 1505859699230, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.7506, 36.4396, 1.92 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arar", "mag": 2.6, "time": 1505859474460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.7831, 36.4511, 2.64 ] } }, +{ "type": "Feature", "properties": { "id": "ci38006608", "mag": 0.96, "time": 1505859334750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.475333, 33.486667, 14.73 ] } }, +{ "type": "Feature", "properties": { "id": "uu60247982", "mag": 1.65, "time": 1505858965080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.420667, 42.524833, 7.59 ] } }, +{ "type": "Feature", "properties": { "id": "ak16859929", "mag": 1.1, "time": 1505857928856, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.6104, 61.9413, 2.9 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605999", "mag": 1.5, "time": 1505856979033, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.7943, 38.658, 7.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875936", "mag": 1.7, "time": 1505856840827, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.652, 53.3989, 20.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606301", "mag": 1.4, "time": 1505856837357, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.7768, 38.66, 6.5 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606300", "mag": 1.4, "time": 1505856822494, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.7817, 38.6647, 4.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16859863", "mag": 1.4, "time": 1505856383099, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.06, 61.1692, 19.6 ] } }, +{ "type": "Feature", "properties": { "id": "uu60247972", "mag": 1.74, "time": 1505856071750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4475, 42.619, 6.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16859852", "mag": 1.7, "time": 1505856067799, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -135.5801, 68.0241, 10.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16859850", "mag": 1.3, "time": 1505856055065, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2245, 61.5244, 4.3 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605994", "mag": 1.2, "time": 1505855929391, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.1076, 37.3659, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar96", "mag": 4.9, "time": 1505855599810, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5112, 15.3218, 46.64 ] } }, +{ "type": "Feature", "properties": { "id": "ci38006584", "mag": 1.62, "time": 1505855343650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.8445, 36.1795, 2.3 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605990", "mag": 1.4, "time": 1505855191998, "felt": 6, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.3633, 38.1896, 5.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16859325", "mag": 2.3, "time": 1505854928991, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9168, 61.6291, 63.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895401", "mag": 1.19, "time": 1505854923520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.721832, 38.778832, 1.61 ] } }, +{ "type": "Feature", "properties": { "id": "ak16859316", "mag": 1.9, "time": 1505854153817, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2675, 59.6779, 106.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar87", "mag": 4.0, "time": 1505854089550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -69.0339, -20.6057, 107.88 ] } }, +{ "type": "Feature", "properties": { "id": "ak16859309", "mag": 2.3, "time": 1505853828556, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.9751, 62.3114, 2.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16859297", "mag": 2.2, "time": 1505853447611, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.476, 59.9101, 122.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16859290", "mag": 3.0, "time": 1505853445730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -158.8511, 55.6543, 46.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16859292", "mag": 3.6, "time": 1505853411703, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.4847, 57.8969, 244.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895391", "mag": 2.22, "time": 1505852777640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.194167, 40.744, 31.83 ] } }, +{ "type": "Feature", "properties": { "id": "uu60247942", "mag": 1.28, "time": 1505852539380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.439833, 42.608667, 6.41 ] } }, +{ "type": "Feature", "properties": { "id": "ak16859266", "mag": 1.1, "time": 1505852431345, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.5411, 60.0259, 13.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar6z", "mag": 5.2, "time": 1505852287190, "felt": 32, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 141.7668, 37.2998, 35.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar6y", "mag": 5.2, "time": 1505852058100, "felt": null, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 150.8423, -5.5637, 99.91 ] } }, +{ "type": "Feature", "properties": { "id": "ak16859257", "mag": 1.1, "time": 1505851589002, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.171, 64.5345, 7.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci38006552", "mag": 1.38, "time": 1505851374120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.498833, 33.866667, -0.49 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895381", "mag": 1.43, "time": 1505851273540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.729333, 36.3275, 5.22 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875922", "mag": 1.3, "time": 1505850452543, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.3232, 58.1622, 6.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875921", "mag": 2.9, "time": 1505849966730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -170.4901, 52.1476, 24.6 ] } }, +{ "type": "Feature", "properties": { "id": "uu60247932", "mag": 1.44, "time": 1505849337250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.421, 42.579, 5.88 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875920", "mag": 1.3, "time": 1505849251567, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.6328, 59.921, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16858730", "mag": 1.2, "time": 1505848519202, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.9009, 61.545, 3.9 ] } }, +{ "type": "Feature", "properties": { "id": "hv61914226", "mag": 1.85, "time": 1505848191950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.283829, 19.389834, 2.69 ] } }, +{ "type": "Feature", "properties": { "id": "ci38006520", "mag": 1.05, "time": 1505847392530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.7695, 36.0195, 2.35 ] } }, +{ "type": "Feature", "properties": { "id": "ci38006512", "mag": 1.61, "time": 1505847142180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.767, 36.0195, 2.27 ] } }, +{ "type": "Feature", "properties": { "id": "ci38006496", "mag": 3.65, "time": 1505846743780, "felt": 24, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.769833, 36.019333, 1.78 ] } }, +{ "type": "Feature", "properties": { "id": "hv61914191", "mag": 1.84, "time": 1505846559260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.249161, 19.378334, 1.88 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875918", "mag": 2.8, "time": 1505846556982, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.8186, 52.0581, 213.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895351", "mag": 1.32, "time": 1505846239310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.104167, 37.325333, -0.31 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895341", "mag": 2.76, "time": 1505846072870, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.359001, 36.981335, 8.57 ] } }, +{ "type": "Feature", "properties": { "id": "ci38006480", "mag": 3.19, "time": 1505846053020, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.767333, 36.019, 1.55 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895286", "mag": 1.33, "time": 1505844883780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.572167, 35.430667, -0.58 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar1y", "mag": 4.6, "time": 1505844881000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -74.1913, -37.2281, 5.95 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar20", "mag": 7.1, "time": 1505844878420, "felt": 2048, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.4952, 18.5539, 51.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16858135", "mag": 1.6, "time": 1505844133798, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.026, 67.0927, 3.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766871", "mag": 1.54, "time": 1505844053390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.846, 36.179167, 2.24 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766863", "mag": 1.44, "time": 1505843932610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.768, 36.018667, 1.61 ] } }, +{ "type": "Feature", "properties": { "id": "nm60207061", "mag": 1.72, "time": 1505843783380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -89.646167, 36.5445, 7.49 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqyy", "mag": 4.5, "time": 1505843446640, "felt": 5, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -72.6161, -31.7548, 29.84 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70235603", "mag": 1.89, "time": 1505842614490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.682, 37.184833, 3.97 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895271", "mag": 1.15, "time": 1505841330820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.259833, 36.753, 11.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqxe", "mag": 4.6, "time": 1505841149400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 128.1444, -7.5033, 158.11 ] } }, +{ "type": "Feature", "properties": { "id": "uu60247882", "mag": 1.62, "time": 1505841064700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.426167, 42.5295, 8.11 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895256", "mag": 1.32, "time": 1505840661480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.598167, 36.752, -0.32 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766807", "mag": 2.45, "time": 1505840210530, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.766, 36.02, 1.86 ] } }, +{ "type": "Feature", "properties": { "id": "uu60247877", "mag": 2.11, "time": 1505840158690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.448833, 42.606, 3.56 ] } }, +{ "type": "Feature", "properties": { "id": "ak16857619", "mag": 2.1, "time": 1505840007502, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.8949, 63.2912, 101.6 ] } }, +{ "type": "Feature", "properties": { "id": "uu60247872", "mag": 1.62, "time": 1505839724910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.458833, 42.607, 3.95 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqvm", "mag": 2.7, "time": 1505839542100, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.469, 42.6077, 7.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895246", "mag": 1.35, "time": 1505839417090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.485667, 35.221333, 6.04 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875914", "mag": 1.9, "time": 1505839174472, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.4077, 58.8832, 118.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766791", "mag": 1.22, "time": 1505838919650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.3645, 33.1855, 10.21 ] } }, +{ "type": "Feature", "properties": { "id": "ak16857617", "mag": 1.6, "time": 1505838902519, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -142.9995, 67.1881, 4.7 ] } }, +{ "type": "Feature", "properties": { "id": "uu60247852", "mag": 2.07, "time": 1505838746530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4455, 42.613833, 1.76 ] } }, +{ "type": "Feature", "properties": { "id": "ak16857602", "mag": 1.1, "time": 1505837962181, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.5253, 60.121, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16857600", "mag": 1.9, "time": 1505837841567, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.1883, 53.9422, 44.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895231", "mag": 2.9, "time": 1505837729840, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.833667, 37.507667, 1.79 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ary5", "mag": 2.9, "time": 1505837727410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4431, 42.6149, 4.8 ] } }, +{ "type": "Feature", "properties": { "id": "uu60247822", "mag": 2.11, "time": 1505837448870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.455167, 42.616, 1.41 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqtm", "mag": 3.1, "time": 1505837140170, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4706, 42.6154, 8.81 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875909", "mag": 2.2, "time": 1505836969879, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4914, 51.7473, 9.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16857094", "mag": 1.1, "time": 1505836528626, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.6176, 61.14, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875907", "mag": 1.5, "time": 1505835821169, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.259, 60.5626, 90.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqsj", "mag": 2.6, "time": 1505835755980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.5135, 36.2854, 4.17 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqsk", "mag": 2.5, "time": 1505835732030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4724, 42.6121, 4.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16857093", "mag": 2.6, "time": 1505835424846, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4652, 51.7084, 16.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqsh", "mag": 3.0, "time": 1505835309120, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4508, 42.6064, 4.14 ] } }, +{ "type": "Feature", "properties": { "id": "ak16857091", "mag": 1.3, "time": 1505835219788, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.0197, 66.1072, 6.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqs7", "mag": 3.5, "time": 1505834833670, "felt": 21, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4429, 42.6135, 8.34 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqwu", "mag": 2.5, "time": 1505834816200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.7965, 36.4516, 6.125 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875904", "mag": 1.6, "time": 1505834730734, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.9141, 57.1404, 29.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766767", "mag": 1.14, "time": 1505834129200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.763833, 36.020667, 1.88 ] } }, +{ "type": "Feature", "properties": { "id": "ak16857088", "mag": 1.5, "time": 1505834082762, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.0429, 60.6104, 77.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqrc", "mag": 4.8, "time": 1505832575280, "felt": null, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 178.0168, 52.0275, 131.51 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875901", "mag": 1.4, "time": 1505831619582, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -137.534, 58.7008, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766711", "mag": 1.96, "time": 1505831425050, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.765667, 36.018833, 1.51 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766703", "mag": 1.15, "time": 1505831411750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.764833, 36.019667, 1.65 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqqm", "mag": 4.5, "time": 1505831278930, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -72.4084, -31.8109, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16856556", "mag": 1.3, "time": 1505831243282, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.7313, 59.8087, 0.9 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606015", "mag": 1.3, "time": 1505831170459, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8959, 38.3975, 10.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16856551", "mag": 1.9, "time": 1505831042494, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.6819, 63.0946, 10.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875898", "mag": 1.7, "time": 1505829915600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2865, 59.7628, 116.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16856544", "mag": 1.6, "time": 1505829548541, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.3607, 61.0755, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895191", "mag": 1.4, "time": 1505828746900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.799667, 38.815333, 3.57 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895181", "mag": 1.21, "time": 1505828239020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.96, 37.587, -0.68 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017262003", "mag": 3.12, "time": 1505828003180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.596, 19.2688, 38.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqpx", "mag": 5.1, "time": 1505827570500, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 53.9953, 27.9548, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895166", "mag": 2.1, "time": 1505827334280, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.801333, 38.709667, 3.88 ] } }, +{ "type": "Feature", "properties": { "id": "ak16856036", "mag": 1.5, "time": 1505826795043, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.9795, 61.8762, 43.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16856032", "mag": 1.6, "time": 1505825636722, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.1838, 62.582, 3.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766679", "mag": 0.96, "time": 1505825558280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.804167, 33.865333, 14.31 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqp7", "mag": 4.4, "time": 1505825308910, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -78.7564, -2.1725, 112.59 ] } }, +{ "type": "Feature", "properties": { "id": "ak16856030", "mag": 3.0, "time": 1505825190453, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -179.1381, 51.2155, 7.2 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605924", "mag": 1.0, "time": 1505824470372, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.0787, 37.3317, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16856028", "mag": 1.3, "time": 1505824029137, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.5369, 59.9737, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16856023", "mag": 1.7, "time": 1505823902403, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.0502, 66.1255, 9.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16856015", "mag": 2.2, "time": 1505823557445, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.013, 66.1279, 12.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16856014", "mag": 1.1, "time": 1505823327376, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3053, 64.2153, 8.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16856012", "mag": 1.2, "time": 1505823307912, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.2687, 63.3135, 1.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16856011", "mag": 2.3, "time": 1505823122176, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -161.4683, 54.3778, 12.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895111", "mag": 1.33, "time": 1505822407460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.809833, 38.802, 3.64 ] } }, +{ "type": "Feature", "properties": { "id": "nm60207021", "mag": 3.8, "time": 1505821648710, "felt": 1485, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -87.909833, 38.423833, 11.68 ] } }, +{ "type": "Feature", "properties": { "id": "ak16855511", "mag": 1.6, "time": 1505821526245, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -144.7265, 65.4529, 0.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875885", "mag": 2.4, "time": 1505821066912, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -170.3853, 52.1246, 33.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895086", "mag": 1.5, "time": 1505820901510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.811333, 38.8115, 2.81 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605917", "mag": 1.0, "time": 1505819713127, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.0296, 37.3121, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766663", "mag": 1.51, "time": 1505819310540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.197333, 34.085167, 9.45 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875884", "mag": 2.8, "time": 1505819249763, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -171.074, 52.1917, 55.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqlv", "mag": 4.4, "time": 1505818453350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -72.3742, -31.7199, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16855501", "mag": 3.4, "time": 1505818346973, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.7971, 56.0595, 12.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16855500", "mag": 2.9, "time": 1505817985167, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 178.3494, 51.1124, 9.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895061", "mag": 1.78, "time": 1505817758790, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.178833, 36.5795, 5.08 ] } }, +{ "type": "Feature", "properties": { "id": "nc72895056", "mag": 2.12, "time": 1505817518530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.177333, 36.582833, 3.53 ] } }, +{ "type": "Feature", "properties": { "id": "uu60247712", "mag": 1.36, "time": 1505817061570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.018167, 44.796, 9.74 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875881", "mag": 1.6, "time": 1505816115601, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.2511, 57.9599, 9.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16855499", "mag": 1.3, "time": 1505815877713, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.8298, 61.5636, 56.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16855498", "mag": 2.3, "time": 1505815751742, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -168.7444, 52.8226, 62.9 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017262002", "mag": 3.05, "time": 1505815582890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.7015, 19.0933, 25.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875878", "mag": 2.3, "time": 1505815056638, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 178.6299, 51.8122, 76.9 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017262001", "mag": 3.03, "time": 1505814906490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.723, 19.2006, 9.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqkv", "mag": 3.1, "time": 1505814230020, "felt": 19, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -96.8094, 35.9883, 6.72 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605909", "mag": 2.0, "time": 1505812861822, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.0799, 37.3335, 2.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766575", "mag": 1.76, "time": 1505810653690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.489167, 32.91, 3.69 ] } }, +{ "type": "Feature", "properties": { "id": "hv61913891", "mag": 1.46, "time": 1505809604540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.2385, 19.383667, 3.069 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awmg", "mag": 4.7, "time": 1505809455110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 162.925, -10.7783, 56.21 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asy2", "mag": 3.0, "time": 1505809273830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -167.747, 56.8207, 54.24 ] } }, +{ "type": "Feature", "properties": { "id": "ak16855496", "mag": 1.1, "time": 1505809181592, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.6103, 61.758, 29.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766567", "mag": 2.63, "time": 1505808839560, "felt": 8, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.053, 33.079333, 9.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16854995", "mag": 1.3, "time": 1505808496915, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -142.3955, 61.6352, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awn2", "mag": 4.8, "time": 1505807930800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.8135, 15.201, 45.46 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqji", "mag": 5.5, "time": 1505807596650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0446, 15.1414, 38.74 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875872", "mag": 2.1, "time": 1505807457953, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -179.2219, 51.3226, 34.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894976", "mag": 1.17, "time": 1505806773770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.792335, 38.809666, 2.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766551", "mag": 1.92, "time": 1505806527540, "felt": 28, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.473833, 34.086, 9.44 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605996", "mag": 1.0, "time": 1505804591858, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.786, 38.6641, 4.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqiw", "mag": 4.9, "time": 1505804582700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5541, 15.6968, 62.85 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894951", "mag": 2.38, "time": 1505803512250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.804667, 38.658333, -1.93 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqim", "mag": 4.9, "time": 1505803059440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 162.5306, -11.0433, 31.53 ] } }, +{ "type": "Feature", "properties": { "id": "ak16858212", "mag": 1.9, "time": 1505803043301, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.8602, 60.3455, 116.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16854482", "mag": 1.5, "time": 1505802327547, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.6967, 63.0934, 11.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766535", "mag": 3.61, "time": 1505802044370, "felt": 9002, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.475667, 34.086667, 10.48 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766527", "mag": 1.21, "time": 1505801932130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.774833, 34.169667, 4.09 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875868", "mag": 1.8, "time": 1505801903580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 178.8368, 51.4427, 38.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16854479", "mag": 1.1, "time": 1505801695119, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.7029, 61.7782, 46.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875866", "mag": 1.4, "time": 1505801525136, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.4992, 53.7654, 79.0 ] } }, +{ "type": "Feature", "properties": { "id": "uw61331061", "mag": 2.06, "time": 1505797453620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -124.194667, 46.453167, 40.56 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766503", "mag": 1.67, "time": 1505797300060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.486333, 32.916167, 3.75 ] } }, +{ "type": "Feature", "properties": { "id": "ak16854474", "mag": 1.9, "time": 1505797038222, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0668, 60.2297, 58.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16853980", "mag": 1.1, "time": 1505796127101, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.3206, 62.3117, 31.2 ] } }, +{ "type": "Feature", "properties": { "id": "uw61330981", "mag": 1.13, "time": 1505795983940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.682, 46.13, 13.15 ] } }, +{ "type": "Feature", "properties": { "id": "ak16853978", "mag": 1.3, "time": 1505795947149, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.1655, 62.2572, 56.3 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605993", "mag": 1.1, "time": 1505795780711, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.1363, 37.4312, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894911", "mag": 1.31, "time": 1505795498990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7385, 38.757333, 2.56 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875861", "mag": 1.1, "time": 1505795298437, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.2708, 60.1059, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017262000", "mag": 3.54, "time": 1505794257010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -68.6603, 17.4281, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875860", "mag": 2.4, "time": 1505793870359, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -160.7298, 54.4321, 27.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875859", "mag": 1.7, "time": 1505793327250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.1948, 59.7387, 99.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16853975", "mag": 1.6, "time": 1505792759926, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -167.4718, 53.5765, 9.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894906", "mag": 1.57, "time": 1505792076170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7735, 38.656833, -0.04 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766479", "mag": 1.69, "time": 1505792016930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.486333, 32.9165, 3.74 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766487", "mag": 1.34, "time": 1505791878570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.484833, 32.910667, 3.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766471", "mag": 1.85, "time": 1505791676460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.4825, 32.916333, 3.63 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894886", "mag": 1.72, "time": 1505789062930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.840667, 37.569167, 0.74 ] } }, +{ "type": "Feature", "properties": { "id": "ak16853477", "mag": 1.0, "time": 1505787688094, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.1719, 66.2583, 2.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875853", "mag": 1.7, "time": 1505787600292, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.3919, 59.6211, 106.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16875852", "mag": 1.1, "time": 1505786552106, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.5941, 61.448, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256309", "mag": 1.39, "time": 1505786055440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.526833, 46.8665, 12.97 ] } }, +{ "type": "Feature", "properties": { "id": "ak16853476", "mag": 1.1, "time": 1505785818136, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.8501, 59.9025, 11.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852984", "mag": 1.1, "time": 1505784566645, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.6396, 62.818, 76.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqg7", "mag": 4.1, "time": 1505784206570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4373, 15.5332, 46.8 ] } }, +{ "type": "Feature", "properties": { "id": "uu60247557", "mag": 1.04, "time": 1505784051560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.714, 41.274333, 9.1 ] } }, +{ "type": "Feature", "properties": { "id": "uu60247547", "mag": 1.47, "time": 1505783841160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.707167, 41.273, 13.52 ] } }, +{ "type": "Feature", "properties": { "id": "hv61913526", "mag": 1.76, "time": 1505783827370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.457833, 19.1825, 36.457 ] } }, +{ "type": "Feature", "properties": { "id": "uu60247542", "mag": 2.67, "time": 1505783530250, "felt": 53, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.715333, 41.2735, 12.54 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852978", "mag": 2.3, "time": 1505783525625, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6267, 63.2162, 130.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852863", "mag": 2.5, "time": 1505781518245, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.0202, 60.2096, 73.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894856", "mag": 0.99, "time": 1505781008310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.827331, 38.841667, 1.75 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852858", "mag": 1.1, "time": 1505780482987, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.8182, 61.2069, 27.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894851", "mag": 1.36, "time": 1505780335820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7775, 38.816, 2.36 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852857", "mag": 1.6, "time": 1505780229532, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.4, 60.0341, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852855", "mag": 1.5, "time": 1505779887968, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.8629, 61.2326, 1.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766415", "mag": 1.9, "time": 1505779853200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.489333, 32.905167, 5.38 ] } }, +{ "type": "Feature", "properties": { "id": "ci37165308", "mag": 1.73, "time": 1505779842240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.488, 32.911333, 4.36 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852849", "mag": 1.7, "time": 1505779013710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9564, 61.0148, 51.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852847", "mag": 1.4, "time": 1505778755901, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.7113, 59.8038, 2.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852839", "mag": 1.8, "time": 1505778454412, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4318, 51.6727, 27.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852350", "mag": 2.0, "time": 1505777928661, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.5948, 59.4167, 88.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766399", "mag": 1.34, "time": 1505777787740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.855667, 36.109333, 3.89 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905714", "mag": 1.0, "time": 1505777724697, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.9455, 64.7711, 1.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766391", "mag": 0.98, "time": 1505777305130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.852333, 36.108833, 4.09 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766383", "mag": 1.52, "time": 1505777027970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.673833, 35.0495, -0.79 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605852", "mag": 1.0, "time": 1505777021809, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.5662, 37.4193, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852327", "mag": 1.3, "time": 1505776382741, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3544, 64.9878, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894836", "mag": 1.11, "time": 1505776268170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.826164, 38.803165, -0.67 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852320", "mag": 2.2, "time": 1505774485259, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.6811, 59.3157, 121.6 ] } }, +{ "type": "Feature", "properties": { "id": "uw61330861", "mag": 1.73, "time": 1505774113220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.3385, 46.609, -0.26 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awm5", "mag": 4.3, "time": 1505773697460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 150.1858, 46.1638, 102.95 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqck", "mag": 3.9, "time": 1505773335560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.2122, -24.1635, 187.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894811", "mag": 1.66, "time": 1505773221810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.814667, 38.797333, 2.92 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aurg", "mag": 3.7, "time": 1505773151260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -161.33, 54.9516, 64.12 ] } }, +{ "type": "Feature", "properties": { "id": "ak16851830", "mag": 1.1, "time": 1505773086095, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.3969, 60.1593, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766351", "mag": 2.36, "time": 1505772988180, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.856, 36.108833, 3.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqc4", "mag": 4.3, "time": 1505772810860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7554, 15.1768, 26.84 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905709", "mag": 1.9, "time": 1505772157260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.3386, 60.1473, 141.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894806", "mag": 1.27, "time": 1505771972190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.114667, 39.267, 3.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905707", "mag": 2.2, "time": 1505771817995, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.2489, 54.4702, 80.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894796", "mag": 2.0, "time": 1505771179880, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.128, 39.249833, 8.56 ] } }, +{ "type": "Feature", "properties": { "id": "ak16851826", "mag": 1.4, "time": 1505770110538, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6751, 61.3285, 49.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766303", "mag": 1.45, "time": 1505769920400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.605, 32.830833, 11.11 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766295", "mag": 1.71, "time": 1505769761910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.604667, 32.8245, 12.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766287", "mag": 2.17, "time": 1505769684730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.606, 32.822667, 12.54 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017261003", "mag": 2.77, "time": 1505769603950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -66.496, 19.0255, 9.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16851820", "mag": 1.8, "time": 1505768968360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.5226, 60.8929, 114.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16851818", "mag": 1.8, "time": 1505768967170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.6844, 60.3627, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "hv61913136", "mag": 2.13, "time": 1505768803830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.602167, 19.474, 2.169 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766271", "mag": 1.2, "time": 1505768642090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.024833, 34.482, 7.73 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766255", "mag": 1.05, "time": 1505767837000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.472833, 34.117167, 12.54 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aq9e", "mag": 4.0, "time": 1505767497800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -72.084, -30.3511, 16.63 ] } }, +{ "type": "Feature", "properties": { "id": "ak16851331", "mag": 3.1, "time": 1505767490141, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -160.4781, 55.9976, 142.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16851328", "mag": 1.1, "time": 1505767149947, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -135.8292, 66.9662, 11.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766231", "mag": 0.99, "time": 1505765477990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.581833, 34.027833, 15.24 ] } }, +{ "type": "Feature", "properties": { "id": "ak16851294", "mag": 1.2, "time": 1505764980957, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.5833, 61.5338, 35.4 ] } }, +{ "type": "Feature", "properties": { "id": "uw61330806", "mag": 1.54, "time": 1505764971380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.54, 46.3245, -0.47 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605816", "mag": 1.4, "time": 1505764963953, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.1157, 37.3834, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605865", "mag": 1.1, "time": 1505764655295, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.1142, 38.3008, 12.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894761", "mag": 1.86, "time": 1505764383660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.820667, 37.543667, 3.73 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aq7z", "mag": 4.9, "time": 1505764292580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.6427, 15.3134, 31.07 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766191", "mag": 0.97, "time": 1505763617780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.450667, 34.371167, 7.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aq71", "mag": 2.7, "time": 1505763144440, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4497, 42.6436, 9.31 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766183", "mag": 1.36, "time": 1505762589870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.1565, 35.016333, -1.02 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256274", "mag": 1.49, "time": 1505762568370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.536167, 46.875, 12.74 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605809", "mag": 1.3, "time": 1505762272549, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.6987, 37.801, 0.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850796", "mag": 1.9, "time": 1505761948762, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.4688, 62.7498, 82.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605855", "mag": 1.3, "time": 1505761056131, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.1168, 37.3993, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766175", "mag": 1.17, "time": 1505760720620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.9445, 34.324333, -1.41 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894741", "mag": 1.25, "time": 1505760426930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.8455, 38.818, 2.33 ] } }, +{ "type": "Feature", "properties": { "id": "uu60247432", "mag": 1.19, "time": 1505760132640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.613667, 40.6905, 8.76 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850168", "mag": 2.1, "time": 1505759367705, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.838, 63.3882, 112.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766167", "mag": 3.51, "time": 1505759058190, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.656502, 31.030666, 5.16 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605797", "mag": 1.7, "time": 1505758994627, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.1288, 37.4056, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850165", "mag": 1.4, "time": 1505758989527, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4112, 62.8303, 102.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905692", "mag": 1.1, "time": 1505758393925, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.8004, 59.9261, 7.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci37766159", "mag": 1.12, "time": 1505757568700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.635, 33.146167, 7.87 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894726", "mag": 0.98, "time": 1505757550510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.418667, 37.284667, 6.16 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905691", "mag": 1.4, "time": 1505757310878, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9735, 60.9138, 37.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850161", "mag": 1.0, "time": 1505757088256, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.0018, 62.0064, 13.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905689", "mag": 1.2, "time": 1505757035772, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8926, 61.2214, 62.6 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017261002", "mag": 2.83, "time": 1505756997070, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -66.5011, 19.09, 29.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aq4m", "mag": 4.3, "time": 1505756979200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -95.2066, 15.6332, 53.99 ] } }, +{ "type": "Feature", "properties": { "id": "ak16849685", "mag": 1.4, "time": 1505755775657, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.6398, 58.3116, 3.1 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605793", "mag": 2.1, "time": 1505755747277, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.0899, 37.3433, 2.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aq3v", "mag": 4.1, "time": 1505755544410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.8487, 15.9949, 55.32 ] } }, +{ "type": "Feature", "properties": { "id": "uu60247422", "mag": 3.28, "time": 1505755278460, "felt": 662, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.609167, 40.700833, 10.96 ] } }, +{ "type": "Feature", "properties": { "id": "ak16849675", "mag": 1.0, "time": 1505754649061, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.0364, 64.4942, 19.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894701", "mag": 1.54, "time": 1505754599760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.869, 36.443167, 15.01 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70235573", "mag": 2.16, "time": 1505754215540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.819333, 37.204, 5.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894696", "mag": 1.11, "time": 1505753360080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.779167, 38.816834, 1.68 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894681", "mag": 2.71, "time": 1505753271320, "felt": 5, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.776833, 38.818833, 1.94 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aq1c", "mag": 4.3, "time": 1505753232560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 19.9297, 40.1065, 16.32 ] } }, +{ "type": "Feature", "properties": { "id": "hv61912961", "mag": 1.88, "time": 1505752987740, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.220333, 19.426333, 30.266 ] } }, +{ "type": "Feature", "properties": { "id": "ak16849646", "mag": 1.9, "time": 1505752045532, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.8846, 59.8511, 56.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905682", "mag": 2.1, "time": 1505751893024, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -175.9783, 51.5536, 48.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905681", "mag": 1.4, "time": 1505751513529, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.5148, 59.7419, 92.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aq9y", "mag": 3.0, "time": 1505751460390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -179.173, 52.0554, 121.43 ] } }, +{ "type": "Feature", "properties": { "id": "uu60247412", "mag": 1.56, "time": 1505751055750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.8355, 39.743833, 1.73 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605780", "mag": 1.0, "time": 1505750947574, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.0248, 38.8721, 3.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894651", "mag": 1.22, "time": 1505750864240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8995, 37.521833, -0.61 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apzi", "mag": 4.5, "time": 1505750058850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 77.1478, 40.9769, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905679", "mag": 1.0, "time": 1505749750880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.3078, 62.9046, 85.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16849178", "mag": 1.3, "time": 1505749184927, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5131, 62.8898, 90.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apyu", "mag": 4.3, "time": 1505748920580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -72.1652, -31.8057, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16849177", "mag": 3.5, "time": 1505748318594, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.7225, 51.7093, 41.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894631", "mag": 1.04, "time": 1505748063110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.787498, 38.798832, -0.32 ] } }, +{ "type": "Feature", "properties": { "id": "hv61912826", "mag": 1.1, "time": 1505748041950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.431667, 19.343833, 9.245 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605847", "mag": 1.0, "time": 1505747832897, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.1332, 37.421, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apya", "mag": 4.7, "time": 1505747639290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5858, 15.1833, 36.89 ] } }, +{ "type": "Feature", "properties": { "id": "ak16848711", "mag": 1.3, "time": 1505747504037, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.7568, 59.8878, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905675", "mag": 2.1, "time": 1505746990876, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.9195, 57.1996, 98.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894616", "mag": 2.19, "time": 1505746390770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.149, 40.217, 6.16 ] } }, +{ "type": "Feature", "properties": { "id": "ak16848704", "mag": 2.3, "time": 1505746286875, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.7477, 53.6076, 54.8 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017261001", "mag": 2.61, "time": 1505746245880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -64.7745, 18.8611, 60.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16848698", "mag": 2.1, "time": 1505746048831, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.6658, 61.6841, 99.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aq9s", "mag": 4.1, "time": 1505745176040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.3907, 51.552, 15.01 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apxn", "mag": 4.9, "time": 1505745090220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -173.9092, -17.3471, 45.41 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apxj", "mag": 4.3, "time": 1505744936080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -72.2186, -31.8431, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605771", "mag": 1.4, "time": 1505744651408, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.1135, 37.3693, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apx5", "mag": 5.6, "time": 1505744352870, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5576, 15.2537, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905668", "mag": 2.5, "time": 1505742582241, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -162.8697, 55.3906, 161.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apwd", "mag": 5.8, "time": 1505742416590, "felt": 129, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -72.147, -31.82, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apz2", "mag": 2.7, "time": 1505742004420, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5215, 46.8389, 9.05 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605759", "mag": 1.7, "time": 1505741994692, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.124, 38.2695, 11.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apw7", "mag": 4.6, "time": 1505741142110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 167.9613, 54.8175, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905665", "mag": 1.6, "time": 1505741113018, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.6727, 58.1121, 86.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905664", "mag": 1.1, "time": 1505740639920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.4494, 63.2584, 114.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894591", "mag": 2.07, "time": 1505739410930, "felt": 5, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.0555, 37.236667, 7.74 ] } }, +{ "type": "Feature", "properties": { "id": "ak16848204", "mag": 1.1, "time": 1505739204689, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.9796, 60.2252, 8.2 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256214", "mag": 2.14, "time": 1505739119730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5825, 46.902333, 13.02 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894586", "mag": 2.01, "time": 1505738526550, "felt": 0, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.378, 36.3415, 3.67 ] } }, +{ "type": "Feature", "properties": { "id": "ak16847753", "mag": 1.3, "time": 1505737613815, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.1555, 60.2089, 8.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apvj", "mag": 5.0, "time": 1505736665230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.9085, -30.4189, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apva", "mag": 4.9, "time": 1505736421580, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9784, 16.2017, 42.11 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894571", "mag": 1.07, "time": 1505736271580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.784332, 38.838333, 0.08 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894556", "mag": 0.97, "time": 1505736021180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.818001, 38.813499, 2.19 ] } }, +{ "type": "Feature", "properties": { "id": "ak16847743", "mag": 2.1, "time": 1505735884769, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.3712, 59.8705, 71.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16847742", "mag": 1.0, "time": 1505735834346, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.8742, 61.715, 45.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905659", "mag": 1.3, "time": 1505735311381, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8392, 63.0532, 129.1 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256209", "mag": 1.05, "time": 1505734177450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.518, 46.853667, 12.03 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256199", "mag": 1.81, "time": 1505733980660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.487833, 46.873667, 12.76 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894526", "mag": 1.16, "time": 1505733885060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.8005, 38.805833, 2.04 ] } }, +{ "type": "Feature", "properties": { "id": "ak16847290", "mag": 1.5, "time": 1505733696824, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.5693, 64.3804, 8.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894516", "mag": 1.04, "time": 1505733506920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.814163, 38.801998, 2.32 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aur7", "mag": 3.1, "time": 1505733485810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -170.7034, 52.2855, 34.99 ] } }, +{ "type": "Feature", "properties": { "id": "ak16847284", "mag": 1.4, "time": 1505732610976, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6388, 61.2241, 50.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765935", "mag": 1.95, "time": 1505732049210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.924667, 34.9205, 5.15 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765927", "mag": 1.35, "time": 1505731803760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.3425, 35.462, 3.59 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894501", "mag": 1.64, "time": 1505731051670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.950333, 41.046833, 9.17 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905652", "mag": 2.0, "time": 1505729940504, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -161.5491, 54.9912, 67.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16846821", "mag": 3.6, "time": 1505729929794, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.5426, 63.5414, 107.9 ] } }, +{ "type": "Feature", "properties": { "id": "hv61912566", "mag": 1.91, "time": 1505728760570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.608167, 19.4375, 2.822 ] } }, +{ "type": "Feature", "properties": { "id": "ak16846819", "mag": 1.2, "time": 1505728039731, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.773, 63.2917, 2.1 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017261000", "mag": 2.03, "time": 1505727803000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.2451, 18.1321, 32.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765911", "mag": 1.15, "time": 1505727350640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.034667, 34.574333, 8.17 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894496", "mag": 1.16, "time": 1505727178720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.815002, 38.806999, 3.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16846817", "mag": 1.3, "time": 1505726686491, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5195, 61.7191, 48.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894491", "mag": 1.99, "time": 1505726671730, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.177167, 36.580167, 5.17 ] } }, +{ "type": "Feature", "properties": { "id": "ak16846815", "mag": 1.4, "time": 1505726488235, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.0878, 61.0048, 19.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16846813", "mag": 1.3, "time": 1505726256030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.0016, 62.7051, 3.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16846811", "mag": 1.2, "time": 1505725663332, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7382, 59.7002, 39.4 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605720", "mag": 1.9, "time": 1505725520932, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.0964, 37.3646, 4.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905644", "mag": 1.4, "time": 1505724853854, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.3038, 57.9653, 66.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894486", "mag": 1.37, "time": 1505724683560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.892833, 39.342333, 17.73 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905643", "mag": 1.3, "time": 1505724218199, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.9106, 60.4014, 74.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16846810", "mag": 1.2, "time": 1505724188489, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.4141, 63.186, 102.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16846807", "mag": 2.8, "time": 1505723956077, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.0917, 53.5664, 54.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16846803", "mag": 1.3, "time": 1505723952516, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.705, 62.5617, 9.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16846799", "mag": 1.9, "time": 1505723888518, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.5274, 59.9845, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16846358", "mag": 1.3, "time": 1505723457765, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9157, 63.5359, 3.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894456", "mag": 1.22, "time": 1505721765430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.157, 36.5615, 3.01 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905637", "mag": 1.8, "time": 1505721695198, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.5368, 53.884, 45.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16846355", "mag": 1.3, "time": 1505721374282, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.8253, 64.8958, 12.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16846352", "mag": 1.3, "time": 1505721334563, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.8755, 64.8906, 14.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16846351", "mag": 1.4, "time": 1505720984307, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.6407, 59.7861, 56.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905633", "mag": 1.2, "time": 1505720070282, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2909, 61.9803, 75.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905632", "mag": 1.3, "time": 1505720064076, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7225, 60.6284, 40.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765871", "mag": 0.96, "time": 1505719770880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.790667, 33.495, 4.99 ] } }, +{ "type": "Feature", "properties": { "id": "hv61912506", "mag": 1.73, "time": 1505719651510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.218167, 19.4285, 29.836 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894436", "mag": 1.05, "time": 1505719249700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.0175, 37.221333, 9.74 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894411", "mag": 1.53, "time": 1505718670360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.827167, 38.8125, 1.64 ] } }, +{ "type": "Feature", "properties": { "id": "ak16845911", "mag": 1.3, "time": 1505718573027, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -161.2238, 64.9935, 6.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894406", "mag": 1.22, "time": 1505718182950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.180167, 36.585333, 5.57 ] } }, +{ "type": "Feature", "properties": { "id": "ak16845908", "mag": 1.1, "time": 1505717899889, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.0029, 61.1046, 1.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16845905", "mag": 2.8, "time": 1505717405495, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.0451, 53.5595, 58.8 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256179", "mag": 2.84, "time": 1505717382030, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.576167, 48.519, 10.89 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765839", "mag": 1.11, "time": 1505716385670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.6075, 32.833667, 11.71 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905628", "mag": 1.2, "time": 1505716158469, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5838, 63.1688, 113.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905627", "mag": 1.2, "time": 1505715377323, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.6661, 60.0063, 5.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16845901", "mag": 1.6, "time": 1505714845138, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.4484, 61.3659, 46.1 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256174", "mag": 1.81, "time": 1505714255290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.529333, 46.9025, 12.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16845458", "mag": 1.9, "time": 1505713543034, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.4235, 61.487, 4.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16845453", "mag": 3.2, "time": 1505712925929, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.0259, 53.5803, 50.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apru", "mag": 5.7, "time": 1505712483490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -12.7162, -18.5262, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605697", "mag": 1.0, "time": 1505711755570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9167, 38.4153, 9.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16845450", "mag": 2.7, "time": 1505711653057, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 179.4353, 51.7384, 88.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16845451", "mag": 1.4, "time": 1505711579811, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0383, 61.8395, 66.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894331", "mag": 2.68, "time": 1505711256010, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -125.213167, 41.036, 15.48 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apre", "mag": 3.6, "time": 1505710149350, "felt": 15, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.457, 42.6072, 5.27 ] } }, +{ "type": "Feature", "properties": { "id": "uu60247312", "mag": 1.94, "time": 1505709538260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.024833, 44.791, 10.06 ] } }, +{ "type": "Feature", "properties": { "id": "ak16845447", "mag": 1.6, "time": 1505709232112, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -167.234, 53.4469, 14.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765759", "mag": 1.11, "time": 1505708432940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.797, 33.496667, 4.85 ] } }, +{ "type": "Feature", "properties": { "id": "nm60206976", "mag": 2.5, "time": 1505708310780, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -89.764167, 36.103833, 7.78 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894281", "mag": 1.78, "time": 1505708211260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.583, 36.899833, 6.75 ] } }, +{ "type": "Feature", "properties": { "id": "ak16845444", "mag": 1.6, "time": 1505708018964, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.0127, 61.0975, 1.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16845440", "mag": 1.7, "time": 1505706867753, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5639, 63.255, 126.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16845438", "mag": 3.0, "time": 1505706621950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0175, 55.7675, 33.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765751", "mag": 1.44, "time": 1505706060150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.797, 33.6865, 17.69 ] } }, +{ "type": "Feature", "properties": { "id": "uu60247287", "mag": 2.42, "time": 1505704855680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.429167, 42.593667, 7.36 ] } }, +{ "type": "Feature", "properties": { "id": "ak16845431", "mag": 2.4, "time": 1505704484262, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.8583, 58.216, 42.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16845430", "mag": 1.1, "time": 1505704418776, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.2714, 58.1899, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256144", "mag": 1.01, "time": 1505704182270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.526333, 46.8725, 13.72 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905611", "mag": 1.0, "time": 1505704113848, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9313, 61.6519, 67.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894211", "mag": 1.84, "time": 1505703109320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.735167, 37.656, 5.91 ] } }, +{ "type": "Feature", "properties": { "id": "ak16845426", "mag": 1.6, "time": 1505702885799, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.6172, 61.5636, 14.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765687", "mag": 1.59, "time": 1505702779150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.919833, 33.9785, 4.46 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605680", "mag": 1.4, "time": 1505702728608, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.713, 38.8287, 9.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16844993", "mag": 1.3, "time": 1505701093513, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.5107, 62.1708, 21.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awky", "mag": 4.1, "time": 1505700898950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.3513, 15.0304, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765671", "mag": 1.43, "time": 1505700367060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.172167, 34.033667, 5.06 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905606", "mag": 1.2, "time": 1505699859087, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8715, 60.6663, 44.3 ] } }, +{ "type": "Feature", "properties": { "id": "uw61330596", "mag": 1.49, "time": 1505699530930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.847333, 47.759167, 17.25 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apq2", "mag": 4.2, "time": 1505699407130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2351, 15.3068, 42.58 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awly", "mag": 4.2, "time": 1505698782750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.1304, 14.9812, 38.39 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905605", "mag": 1.0, "time": 1505698554304, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.5172, 62.1736, 24.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894176", "mag": 2.03, "time": 1505698095820, "felt": 171, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.295333, 37.912, 2.97 ] } }, +{ "type": "Feature", "properties": { "id": "us2000appq", "mag": 4.5, "time": 1505697812820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 159.3367, 53.381, 85.64 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765639", "mag": 1.01, "time": 1505697641450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.7125, 33.986833, 15.48 ] } }, +{ "type": "Feature", "properties": { "id": "us2000appj", "mag": 4.2, "time": 1505697430690, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -69.5275, -17.5255, 167.68 ] } }, +{ "type": "Feature", "properties": { "id": "ak16844988", "mag": 1.0, "time": 1505697245375, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.1193, 62.3401, 0.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765631", "mag": 1.87, "time": 1505697080810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.650333, 36.996833, -0.56 ] } }, +{ "type": "Feature", "properties": { "id": "ak16905602", "mag": 1.4, "time": 1505696884087, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.1499, 61.9617, 114.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16844556", "mag": 1.5, "time": 1505696691069, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.8744, 60.2484, 9.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000azbk", "mag": 4.0, "time": 1505696468620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5206, 14.824, 18.19 ] } }, +{ "type": "Feature", "properties": { "id": "ak16844553", "mag": 1.3, "time": 1505696463448, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.4081, 64.6136, 20.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894161", "mag": 1.21, "time": 1505695849630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.818833, 37.41, -0.31 ] } }, +{ "type": "Feature", "properties": { "id": "us2000awku", "mag": 4.1, "time": 1505694807240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 145.306, 19.0286, 202.23 ] } }, +{ "type": "Feature", "properties": { "id": "us2000app7", "mag": 4.4, "time": 1505694748030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 119.3564, -8.1346, 41.72 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605668", "mag": 1.2, "time": 1505694738920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.3624, 37.0509, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16844544", "mag": 2.0, "time": 1505694295643, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7281, 60.3555, 46.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16844543", "mag": 1.8, "time": 1505694278381, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.7896, 59.8626, 4.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894151", "mag": 1.42, "time": 1505693902060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.912833, 37.621667, 2.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16844541", "mag": 1.3, "time": 1505693551555, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.791, 61.7452, 48.2 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256109", "mag": 1.41, "time": 1505690846740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.522, 46.869667, 12.91 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765583", "mag": 1.3, "time": 1505690496480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.673167, 35.042833, -0.82 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873959", "mag": 1.1, "time": 1505690288149, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.4144, 67.2216, 11.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16844094", "mag": 1.9, "time": 1505690276630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.3972, 53.7854, 6.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apnm", "mag": 4.9, "time": 1505689940400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 149.5672, -4.6379, 588.19 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256099", "mag": 2.34, "time": 1505689339390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5195, 46.899167, 12.28 ] } }, +{ "type": "Feature", "properties": { "id": "ak16844091", "mag": 1.5, "time": 1505688162418, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.5592, 60.9727, 72.2 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256084", "mag": 1.49, "time": 1505688150190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.8165, 46.9305, 13.74 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894131", "mag": 0.95, "time": 1505687822870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.026667, 36.453333, 2.98 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894126", "mag": 1.46, "time": 1505687740270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.618333, 36.970833, 5.35 ] } }, +{ "type": "Feature", "properties": { "id": "ak16844087", "mag": 1.3, "time": 1505686236328, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3499, 60.4807, 6.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16844084", "mag": 1.7, "time": 1505686047172, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.7406, 64.6981, 9.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16844079", "mag": 2.1, "time": 1505685489298, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3304, 60.4706, 9.6 ] } }, +{ "type": "Feature", "properties": { "id": "uw61330461", "mag": 2.46, "time": 1505684983130, "felt": 15, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.725333, 47.439333, 22.35 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873952", "mag": 2.2, "time": 1505684866449, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -169.006, 52.386, 9.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894116", "mag": 1.14, "time": 1505684450170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.571833, 37.947167, 8.37 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873951", "mag": 1.3, "time": 1505684432066, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.6357, 60.5724, 2.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16843656", "mag": 1.6, "time": 1505683789980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1167, 59.7703, 41.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16843652", "mag": 1.6, "time": 1505683291823, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.4894, 61.5289, 25.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894101", "mag": 1.41, "time": 1505682978360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.834, 37.496, 1.06 ] } }, +{ "type": "Feature", "properties": { "id": "ak16843651", "mag": 2.6, "time": 1505682712646, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 178.4711, 51.686, 75.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894096", "mag": 0.99, "time": 1505682599530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.816167, 37.455833, 1.06 ] } }, +{ "type": "Feature", "properties": { "id": "ak16843650", "mag": 1.2, "time": 1505682068077, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5842, 61.7746, 3.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894086", "mag": 1.35, "time": 1505681812610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.973667, 36.395167, 4.69 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894081", "mag": 1.91, "time": 1505681477080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.809167, 38.797667, 3.52 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894076", "mag": 1.47, "time": 1505681470510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.810167, 38.799167, 3.08 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873946", "mag": 1.4, "time": 1505680958230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1812, 62.2538, 76.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apkx", "mag": 4.9, "time": 1505680147260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.9501, -18.9829, 129.26 ] } }, +{ "type": "Feature", "properties": { "id": "ak16843225", "mag": 1.3, "time": 1505680062920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.5209, 60.1956, 82.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765519", "mag": 1.42, "time": 1505680024130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.293, 35.488167, 2.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873944", "mag": 1.3, "time": 1505679233862, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2975, 62.163, 79.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873943", "mag": 1.8, "time": 1505678992249, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.8219, 51.8825, 86.4 ] } }, +{ "type": "Feature", "properties": { "id": "uw61330431", "mag": 1.0, "time": 1505678333060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.5365, 47.603667, 19.51 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765487", "mag": 1.12, "time": 1505676865320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.608667, 32.830167, 11.82 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apke", "mag": 4.1, "time": 1505676865110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -87.5905, 12.0757, 53.01 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apkd", "mag": 3.9, "time": 1505676791370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -70.2379, -31.7388, 121.68 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765479", "mag": 1.54, "time": 1505676576290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.605333, 32.8245, 11.96 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apkc", "mag": 2.5, "time": 1505676527950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4244, 42.5958, 5.8 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605653", "mag": 1.3, "time": 1505676457309, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.12, 38.2855, 13.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894061", "mag": 1.21, "time": 1505675373140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.059667, 36.477833, 6.98 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apk4", "mag": 3.1, "time": 1505674381070, "felt": 7, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -96.9818, 35.7788, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16842798", "mag": 1.4, "time": 1505672288384, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.7121, 63.5719, 4.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16842797", "mag": 2.7, "time": 1505669173773, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4976, 51.6544, 7.8 ] } }, +{ "type": "Feature", "properties": { "id": "mb80256039", "mag": 1.09, "time": 1505668834370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.6775, 46.891833, 15.96 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873938", "mag": 1.2, "time": 1505668625975, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.5592, 62.857, 82.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765423", "mag": 1.4, "time": 1505668324590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.831333, 32.775833, 2.46 ] } }, +{ "type": "Feature", "properties": { "id": "ak16842795", "mag": 1.1, "time": 1505668022720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.4003, 64.8531, 2.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72894026", "mag": 1.3, "time": 1505667983860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.734667, 38.788167, 1.43 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873936", "mag": 1.6, "time": 1505667107903, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.0584, 57.21, 33.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765415", "mag": 1.52, "time": 1505666643390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.833167, 32.781833, 2.39 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765407", "mag": 0.98, "time": 1505666358680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.273667, 33.981333, 6.22 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at5v", "mag": 4.3, "time": 1505665820280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 127.2591, 0.908, 157.83 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017260000", "mag": 2.31, "time": 1505665148110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.9698, 19.0821, 23.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apj3", "mag": 2.6, "time": 1505664664460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4059, 42.5497, 11.14 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apj0", "mag": 2.7, "time": 1505663998840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4107, 42.5429, 8.67 ] } }, +{ "type": "Feature", "properties": { "id": "uw61330391", "mag": 1.11, "time": 1505663462920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.04, 46.880167, 6.02 ] } }, +{ "type": "Feature", "properties": { "id": "uu60247022", "mag": 1.06, "time": 1505663122580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.025833, 44.790333, 9.98 ] } }, +{ "type": "Feature", "properties": { "id": "nn00606540", "mag": 1.3, "time": 1505663040033, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.0921, 41.885, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873932", "mag": 1.9, "time": 1505662296127, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.8489, 51.9624, 111.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at5n", "mag": 4.5, "time": 1505662282900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 140.7612, 44.1688, 33.57 ] } }, +{ "type": "Feature", "properties": { "id": "mb80255969", "mag": 2.04, "time": 1505662108810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.516, 46.881333, 14.94 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at5p", "mag": 4.5, "time": 1505662091100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 149.0118, -6.3464, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873931", "mag": 1.4, "time": 1505662034661, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -144.362, 63.1318, 2.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at68", "mag": 4.3, "time": 1505661360280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 148.9733, -6.4551, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16841969", "mag": 1.1, "time": 1505661169528, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.6029, 66.5697, 13.3 ] } }, +{ "type": "Feature", "properties": { "id": "mb80255949", "mag": 1.49, "time": 1505659897070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.519, 46.855, 14.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apij", "mag": 5.4, "time": 1505659803240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -173.6428, -16.6386, 30.39 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at5x", "mag": 5.0, "time": 1505659691430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 92.0846, 12.809, 27.48 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765367", "mag": 1.03, "time": 1505659458990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.19, 33.2585, 9.58 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893976", "mag": 1.19, "time": 1505659223910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.825, 37.453, 1.57 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at5m", "mag": 4.9, "time": 1505658989080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 149.1591, -6.3567, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apie", "mag": 4.5, "time": 1505658574670, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 24.0015, 39.2721, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16841552", "mag": 1.3, "time": 1505658549717, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.9309, 62.6606, 59.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apif", "mag": 5.7, "time": 1505658367620, "felt": 0, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 148.8708, -6.3113, 18.92 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at5l", "mag": 4.3, "time": 1505658365190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -17.9505, 64.5019, 9.15 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aza1", "mag": 4.2, "time": 1505658191320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5959, 15.2169, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at6b", "mag": 4.6, "time": 1505658184020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -17.6137, 64.4904, 8.23 ] } }, +{ "type": "Feature", "properties": { "id": "ak16841550", "mag": 1.4, "time": 1505657865000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.8499, 59.8804, 5.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765335", "mag": 1.11, "time": 1505657294840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.367, 33.357167, 9.18 ] } }, +{ "type": "Feature", "properties": { "id": "ak16841549", "mag": 1.4, "time": 1505657219284, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.0876, 69.5184, 4.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893941", "mag": 1.51, "time": 1505657160730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.818333, 38.818167, 2.23 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893946", "mag": 1.02, "time": 1505657152440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.817001, 38.8185, 2.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873926", "mag": 1.7, "time": 1505656923604, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.8082, 60.1773, 106.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873925", "mag": 1.9, "time": 1505656654419, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.6293, 59.5728, 120.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765327", "mag": 2.88, "time": 1505656629430, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.882333, 31.6215, 9.25 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at5k", "mag": 4.1, "time": 1505656609750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 126.5305, 1.7746, 37.54 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893936", "mag": 0.98, "time": 1505656502420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.125667, 36.566167, 8.44 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at5i", "mag": 4.4, "time": 1505655648380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.9394, -17.3298, 553.92 ] } }, +{ "type": "Feature", "properties": { "id": "se60044613", "mag": 2.03, "time": 1505655579030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -85.053333, 35.561333, 15.47 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765311", "mag": 1.07, "time": 1505655296260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.090333, 33.473833, 14.65 ] } }, +{ "type": "Feature", "properties": { "id": "ak16841547", "mag": 1.9, "time": 1505655282227, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.7794, 63.9496, 114.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at5r", "mag": 4.9, "time": 1505655030310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -11.7611, -21.01, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000as44", "mag": 2.6, "time": 1505654924870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.7236, 51.4933, 34.35 ] } }, +{ "type": "Feature", "properties": { "id": "ak16841538", "mag": 2.3, "time": 1505654819006, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.6722, 62.9044, 66.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765303", "mag": 0.97, "time": 1505654141860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.922167, 33.9755, 4.94 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aphx", "mag": 4.0, "time": 1505653928680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4533, 15.5042, 7.94 ] } }, +{ "type": "Feature", "properties": { "id": "ak16841537", "mag": 1.0, "time": 1505653531820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.3466, 61.07, 12.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893916", "mag": 0.99, "time": 1505653446980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.835, 37.479333, 0.86 ] } }, +{ "type": "Feature", "properties": { "id": "ak16841536", "mag": 1.4, "time": 1505653266021, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.6794, 67.9633, 14.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16841136", "mag": 1.5, "time": 1505652267061, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.9646, 53.8971, 6.6 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605626", "mag": 1.0, "time": 1505652081143, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.2815, 36.537, 7.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16841133", "mag": 1.8, "time": 1505651930739, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.7652, 62.1126, 23.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16841130", "mag": 2.2, "time": 1505651632523, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.454, 59.2923, 97.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765271", "mag": 1.39, "time": 1505650827610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.021167, 33.921, 2.44 ] } }, +{ "type": "Feature", "properties": { "id": "hv61911226", "mag": 1.91, "time": 1505650411260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.478668, 19.212334, 38.03 ] } }, +{ "type": "Feature", "properties": { "id": "ak16841124", "mag": 2.1, "time": 1505649687852, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.7865, 65.3345, 13.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893881", "mag": 1.23, "time": 1505648682040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.543833, 37.339667, 10.06 ] } }, +{ "type": "Feature", "properties": { "id": "ak16840722", "mag": 3.2, "time": 1505648575230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.7144, 57.2975, 42.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at5g", "mag": 4.3, "time": 1505647937400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 166.6171, -11.7459, 251.44 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873911", "mag": 2.6, "time": 1505647578270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -135.7891, 66.3882, 37.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873910", "mag": 2.0, "time": 1505647575716, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.55, 57.7487, 89.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873909", "mag": 2.8, "time": 1505647412246, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -135.7412, 66.3682, 34.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16840719", "mag": 2.1, "time": 1505647228188, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.4607, 60.5815, 14.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765239", "mag": 1.03, "time": 1505646849520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.920667, 33.972167, 5.29 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aph6", "mag": 4.2, "time": 1505646653440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.3399, -21.9058, 192.78 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aph5", "mag": 4.7, "time": 1505646260660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 127.0437, 3.6252, 68.15 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873907", "mag": 2.2, "time": 1505645846935, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4823, 51.6608, 13.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873906", "mag": 1.2, "time": 1505645773090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.3827, 53.8702, 12.1 ] } }, +{ "type": "Feature", "properties": { "id": "uw61330311", "mag": 1.94, "time": 1505644617240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.041167, 46.879167, 6.84 ] } }, +{ "type": "Feature", "properties": { "id": "ak16840715", "mag": 1.5, "time": 1505644280463, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.605, 61.6723, 29.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765223", "mag": 1.02, "time": 1505644185880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.465667, 34.376833, 9.74 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765215", "mag": 1.28, "time": 1505644151980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.358167, 33.415667, 12.48 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at5e", "mag": 4.5, "time": 1505644031790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 92.0628, 12.7773, 33.35 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873903", "mag": 1.4, "time": 1505643609236, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5971, 61.5891, 59.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16840713", "mag": 1.9, "time": 1505643118540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -144.0384, 63.1445, 14.8 ] } }, +{ "type": "Feature", "properties": { "id": "hv61911016", "mag": 2.48, "time": 1505641665420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.593167, 19.476, 2.731 ] } }, +{ "type": "Feature", "properties": { "id": "ak16840350", "mag": 1.1, "time": 1505641100972, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.8915, 64.848, 8.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at5c", "mag": 4.7, "time": 1505640684330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -26.4288, -59.7896, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16840314", "mag": 2.8, "time": 1505640505656, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.6831, 60.3761, 2.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apgy", "mag": 4.9, "time": 1505640302130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 141.2485, 37.3415, 54.96 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at65", "mag": 4.6, "time": 1505640090990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -13.5314, -7.0219, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000as3y", "mag": 2.7, "time": 1505639953270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -176.1147, 51.5611, 45.65 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at5a", "mag": 4.8, "time": 1505639681290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -13.1689, -7.0877, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16840312", "mag": 2.1, "time": 1505638931288, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0719, 60.2719, 130.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16840302", "mag": 2.8, "time": 1505638686114, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.2164, 60.4788, 97.5 ] } }, +{ "type": "Feature", "properties": { "id": "uu60246942", "mag": 1.01, "time": 1505637537950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.025833, 44.786167, 7.95 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893791", "mag": 1.48, "time": 1505637347930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.879167, 37.109167, 2.16 ] } }, +{ "type": "Feature", "properties": { "id": "ak16839942", "mag": 1.9, "time": 1505637129909, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8564, 60.3231, 63.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893786", "mag": 1.14, "time": 1505636971290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.737335, 38.786167, 0.85 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893781", "mag": 2.61, "time": 1505636516400, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.117, 36.594333, 6.98 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apg4", "mag": 4.6, "time": 1505636241220, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -82.1696, 7.5057, 23.33 ] } }, +{ "type": "Feature", "properties": { "id": "ak16839932", "mag": 1.1, "time": 1505636239228, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.8157, 63.2668, 2.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apg0", "mag": 4.1, "time": 1505634585840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -66.7666, -23.8893, 236.18 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765143", "mag": 2.2, "time": 1505634363500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.373667, 32.9405, 7.78 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605603", "mag": 1.8, "time": 1505634209242, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8894, 38.3778, 11.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apfv", "mag": 2.4, "time": 1505634047190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4463, 42.5857, 4.34 ] } }, +{ "type": "Feature", "properties": { "id": "ak16839551", "mag": 1.9, "time": 1505633391424, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.7184, 59.603, 74.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893741", "mag": 1.84, "time": 1505633100770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.834167, 37.493833, 1.09 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apft", "mag": 2.6, "time": 1505632181750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4391, 42.6077, 6.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765127", "mag": 0.98, "time": 1505632149420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.605167, 32.828333, 10.94 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893701", "mag": 1.35, "time": 1505631284810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.952833, 37.588167, 1.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apfk", "mag": 4.3, "time": 1505630160580, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -71.6223, -35.7292, 85.77 ] } }, +{ "type": "Feature", "properties": { "id": "ak16839518", "mag": 2.0, "time": 1505629372703, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.7555, 60.0405, 18.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893646", "mag": 1.36, "time": 1505628925460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.736667, 38.757, 1.79 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873889", "mag": 2.9, "time": 1505628904808, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.5935, 53.8081, 78.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apfd", "mag": 2.9, "time": 1505628801990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4531, 42.5908, 5.17 ] } }, +{ "type": "Feature", "properties": { "id": "uu60246882", "mag": 1.05, "time": 1505628704550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.836, 44.307333, 7.31 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873888", "mag": 1.1, "time": 1505628661963, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.5848, 64.1727, 10.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apfa", "mag": 4.9, "time": 1505628478300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9805, 16.0409, 45.23 ] } }, +{ "type": "Feature", "properties": { "id": "uu60246872", "mag": 1.16, "time": 1505628425450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.817667, 44.294, 7.61 ] } }, +{ "type": "Feature", "properties": { "id": "uu60246867", "mag": 1.13, "time": 1505628332210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.828167, 44.305167, 7.48 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apf6", "mag": 4.5, "time": 1505628213110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -95.0121, 16.1058, 52.57 ] } }, +{ "type": "Feature", "properties": { "id": "ak16839149", "mag": 1.6, "time": 1505628012027, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.2, 62.1778, 6.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apf5", "mag": 4.3, "time": 1505627809940, "felt": 7, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -88.5423, 14.4117, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765039", "mag": 1.19, "time": 1505627007650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.0955, 36.761167, 1.69 ] } }, +{ "type": "Feature", "properties": { "id": "uu60246847", "mag": 3.15, "time": 1505626724050, "felt": 5, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.841667, 44.302333, 7.53 ] } }, +{ "type": "Feature", "properties": { "id": "uu60246837", "mag": 2.04, "time": 1505626455220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.822333, 44.293667, 7.53 ] } }, +{ "type": "Feature", "properties": { "id": "ci37765023", "mag": 1.52, "time": 1505626163830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.797833, 33.501167, 4.62 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apeu", "mag": 4.4, "time": 1505625898530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -86.4078, 10.7018, 35.32 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893621", "mag": 1.12, "time": 1505625800310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.810165, 38.820499, 1.92 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764991", "mag": 1.62, "time": 1505625396010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.928167, 35.9015, 5.28 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764983", "mag": 1.96, "time": 1505624889150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.181, 33.187833, 5.86 ] } }, +{ "type": "Feature", "properties": { "id": "ak16838778", "mag": 1.4, "time": 1505624855438, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.4712, 59.8595, 42.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893601", "mag": 1.37, "time": 1505624608110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.8885, 37.105, 1.63 ] } }, +{ "type": "Feature", "properties": { "id": "ak16838775", "mag": 3.2, "time": 1505624284096, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -163.1812, 54.0118, 9.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apeh", "mag": 4.3, "time": 1505624194760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -105.7123, 17.7366, 31.43 ] } }, +{ "type": "Feature", "properties": { "id": "ak16838774", "mag": 1.8, "time": 1505623546848, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.7399, 59.8813, 5.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16838756", "mag": 1.2, "time": 1505622986310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.8141, 63.2696, 2.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16838752", "mag": 1.7, "time": 1505622626171, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -158.3598, 64.3838, 13.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764967", "mag": 0.95, "time": 1505622039760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.1755, 33.965, 15.93 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873881", "mag": 2.7, "time": 1505621586321, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -169.8861, 52.4075, 59.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873880", "mag": 1.0, "time": 1505621507758, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.3176, 61.144, 19.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16838400", "mag": 1.9, "time": 1505621153075, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1301, 60.8625, 64.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16838393", "mag": 2.5, "time": 1505620853506, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8794, 60.7582, 60.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16838388", "mag": 2.8, "time": 1505620146422, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.7851, 59.8817, 2.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893571", "mag": 1.03, "time": 1505619694280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.821167, 38.807999, 1.94 ] } }, +{ "type": "Feature", "properties": { "id": "ak16838386", "mag": 2.2, "time": 1505619628700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.9053, 67.6564, 13.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893561", "mag": 1.07, "time": 1505619296320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.822502, 38.808998, 1.93 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764903", "mag": 1.12, "time": 1505618790010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.147333, 34.5405, 9.83 ] } }, +{ "type": "Feature", "properties": { "id": "ak16838042", "mag": 1.6, "time": 1505617352105, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.5056, 61.4142, 8.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16838020", "mag": 1.2, "time": 1505616366369, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.6618, 60.5653, 6.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16838003", "mag": 1.0, "time": 1505615565391, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.2146, 64.7331, 17.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764863", "mag": 1.1, "time": 1505613255300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.709667, 33.653333, 15.82 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764847", "mag": 1.21, "time": 1505612591880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.687167, 33.6285, 12.15 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764839", "mag": 1.47, "time": 1505612490180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.927167, 33.971833, 17.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16837647", "mag": 1.8, "time": 1505611875649, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.771, 59.8672, 1.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16873869", "mag": 1.7, "time": 1505609079690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.474, 51.671, 16.0 ] } }, +{ "type": "Feature", "properties": { "id": "hv61910741", "mag": 2.42, "time": 1505608202930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.177667, 19.442, 41.639 ] } }, +{ "type": "Feature", "properties": { "id": "ak16836972", "mag": 2.6, "time": 1505606832814, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.3048, 51.6525, 97.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764815", "mag": 0.95, "time": 1505606822450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.746333, 33.887, 16.59 ] } }, +{ "type": "Feature", "properties": { "id": "ak16836965", "mag": 2.3, "time": 1505606388180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.7659, 59.8663, 5.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16836961", "mag": 2.4, "time": 1505606178328, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.7941, 59.8509, 5.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16836957", "mag": 1.8, "time": 1505606050093, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.89, 59.8885, 15.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16860570", "mag": 1.4, "time": 1505605718038, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.8821, 59.8989, 17.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16860569", "mag": 1.6, "time": 1505605674005, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.8902, 59.9059, 15.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16860568", "mag": 1.9, "time": 1505605456859, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.8916, 59.9103, 15.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16860567", "mag": 2.3, "time": 1505605410411, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.9, 59.889, 12.6 ] } }, +{ "type": "Feature", "properties": { "id": "uw61330071", "mag": 2.57, "time": 1505605382130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -124.863333, 45.526833, 36.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apcc", "mag": 5.1, "time": 1505605083280, "felt": 218, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ -136.7498, 59.9037, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apbv", "mag": 3.9, "time": 1505604419110, "felt": 198, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -96.6989, 35.8586, 2.57 ] } }, +{ "type": "Feature", "properties": { "id": "ak16836912", "mag": 2.9, "time": 1505604383308, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 178.6017, 51.905, 128.2 ] } }, +{ "type": "Feature", "properties": { "id": "uw61329986", "mag": 1.23, "time": 1505604005810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.754167, 46.857333, 1.43 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apbu", "mag": 4.7, "time": 1505603696310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -14.0114, -17.7554, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16860564", "mag": 1.6, "time": 1505603516964, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1524, 61.3778, 62.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apbm", "mag": 4.5, "time": 1505603442050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.1822, 15.4761, 67.03 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893446", "mag": 2.29, "time": 1505603337140, "felt": 5, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.616833, 36.971, 4.79 ] } }, +{ "type": "Feature", "properties": { "id": "ak16860563", "mag": 1.5, "time": 1505603223363, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.5667, 57.9908, 15.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16860562", "mag": 1.6, "time": 1505602163820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0011, 60.0807, 110.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16836589", "mag": 1.7, "time": 1505601390855, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.7769, 62.4045, 59.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893436", "mag": 1.34, "time": 1505600967450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.834167, 37.493, 0.66 ] } }, +{ "type": "Feature", "properties": { "id": "uw61329976", "mag": 1.03, "time": 1505600388700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.491167, 46.067333, 18.24 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764791", "mag": 1.29, "time": 1505599746390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.431333, 33.040167, 10.42 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893421", "mag": 1.75, "time": 1505599309380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.164333, 35.816, 11.62 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apln", "mag": 3.8, "time": 1505599105290, "felt": 27, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 139.4711, 35.839, 65.43 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893416", "mag": 2.39, "time": 1505598962550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -124.606167, 40.391, 23.43 ] } }, +{ "type": "Feature", "properties": { "id": "ak16836269", "mag": 2.6, "time": 1505598312964, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.1504, 57.6803, 1.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apay", "mag": 4.1, "time": 1505597546760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4078, 15.1552, 27.65 ] } }, +{ "type": "Feature", "properties": { "id": "ak16860558", "mag": 1.5, "time": 1505597186774, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8073, 63.0653, 123.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893411", "mag": 1.07, "time": 1505596690170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.793999, 38.805332, 0.54 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764743", "mag": 1.25, "time": 1505596431740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.179, 33.192167, 7.19 ] } }, +{ "type": "Feature", "properties": { "id": "us2000apa3", "mag": 5.2, "time": 1505595657570, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 159.8208, 52.9335, 55.59 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893406", "mag": 1.68, "time": 1505595567120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.832833, 37.5715, 2.76 ] } }, +{ "type": "Feature", "properties": { "id": "ak16835937", "mag": 1.2, "time": 1505594309155, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.7782, 63.4422, 11.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16835935", "mag": 1.3, "time": 1505593468147, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0825, 63.2217, 0.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764719", "mag": 1.01, "time": 1505593021350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.509667, 36.069667, 3.41 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764711", "mag": 1.86, "time": 1505592937400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.217, 32.373167, 19.88 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ap9e", "mag": 4.2, "time": 1505592897770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -66.6768, -23.7075, 201.03 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605530", "mag": 1.0, "time": 1505591425440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.9, 39.4039, 6.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893386", "mag": 1.01, "time": 1505591244480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.504167, 37.923833, 7.96 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ap8u", "mag": 5.1, "time": 1505590529510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.552, 15.3031, 17.06 ] } }, +{ "type": "Feature", "properties": { "id": "ak16835905", "mag": 2.1, "time": 1505590055161, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0556, 59.9293, 124.0 ] } }, +{ "type": "Feature", "properties": { "id": "uu60246652", "mag": 1.36, "time": 1505589841530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.020833, 44.802, 10.59 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764687", "mag": 1.0, "time": 1505588714630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.973333, 33.989, 6.67 ] } }, +{ "type": "Feature", "properties": { "id": "ak16835606", "mag": 2.1, "time": 1505588651481, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.7021, 67.8201, 4.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764679", "mag": 1.11, "time": 1505588640970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.2045, 34.993167, -0.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ap88", "mag": 4.3, "time": 1505588283560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7095, 15.6575, 33.63 ] } }, +{ "type": "Feature", "properties": { "id": "ak16860552", "mag": 2.1, "time": 1505587762267, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2692, 60.1941, 137.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16860551", "mag": 1.2, "time": 1505586754071, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.2984, 62.5136, 52.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764631", "mag": 1.09, "time": 1505586635400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.791667, 33.507667, 4.61 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764623", "mag": 1.32, "time": 1505586305110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.975667, 33.992333, 5.71 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893361", "mag": 1.14, "time": 1505585751450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.8095, 38.823167, 1.14 ] } }, +{ "type": "Feature", "properties": { "id": "ak16835287", "mag": 2.1, "time": 1505584069266, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.8156, 57.4983, 73.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ap76", "mag": 4.0, "time": 1505583967320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -95.5572, 15.6925, 24.12 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ap74", "mag": 4.7, "time": 1505583533380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 142.7408, 24.878, 57.27 ] } }, +{ "type": "Feature", "properties": { "id": "ak16860549", "mag": 1.4, "time": 1505583090155, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0305, 61.8843, 68.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764599", "mag": 1.28, "time": 1505582839910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.878167, 35.360667, 7.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ap78", "mag": 4.9, "time": 1505582156450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 161.507, -10.1846, 49.82 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ap6d", "mag": 3.0, "time": 1505582077650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4285, 42.5847, 7.15 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ap6b", "mag": 4.6, "time": 1505581929340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -74.1918, -37.2167, 6.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ap64", "mag": 4.5, "time": 1505581636660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -95.0682, 16.1115, 35.63 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893331", "mag": 1.49, "time": 1505581158890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.337833, 37.820167, -0.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16860548", "mag": 2.1, "time": 1505580632689, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.7764, 56.9377, 2.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893326", "mag": 1.43, "time": 1505580258840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.711, 38.750833, 1.46 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893316", "mag": 1.6, "time": 1505579747930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.717167, 38.752667, 1.24 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893306", "mag": 1.39, "time": 1505579471580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.0075, 37.570667, 2.07 ] } }, +{ "type": "Feature", "properties": { "id": "hv61910186", "mag": 1.68, "time": 1505579377040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.611, 19.430167, 2.332 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764559", "mag": 1.5, "time": 1505579023330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.801833, 34.514833, 12.76 ] } }, +{ "type": "Feature", "properties": { "id": "ak16834974", "mag": 1.6, "time": 1505578926267, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.7481, 62.8102, 9.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16834965", "mag": 2.6, "time": 1505578647951, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7871, 61.8971, 60.5 ] } }, +{ "type": "Feature", "properties": { "id": "mb80255754", "mag": 1.22, "time": 1505578208020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.489667, 44.705667, 13.34 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893286", "mag": 1.35, "time": 1505577465010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.047, 36.467, 7.96 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605503", "mag": 1.0, "time": 1505577266743, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.9133, 37.0358, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16834664", "mag": 2.4, "time": 1505577104470, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.431, 64.4709, 16.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ap48", "mag": 2.5, "time": 1505575595120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4328, 42.5757, 6.87 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893281", "mag": 1.04, "time": 1505575420020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.895333, 37.565, -1.35 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ap45", "mag": 2.6, "time": 1505574778570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4287, 42.5771, 8.55 ] } }, +{ "type": "Feature", "properties": { "id": "ak16834651", "mag": 1.1, "time": 1505574443625, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.8572, 64.7619, 12.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893271", "mag": 1.41, "time": 1505574428990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.946833, 37.638167, 2.02 ] } }, +{ "type": "Feature", "properties": { "id": "ak16860541", "mag": 2.0, "time": 1505574078688, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.3496, 59.7545, 127.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764535", "mag": 1.64, "time": 1505573652280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.1775, 33.193, 4.38 ] } }, +{ "type": "Feature", "properties": { "id": "ak16834350", "mag": 1.4, "time": 1505572849209, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.9009, 64.7582, 0.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ap3f", "mag": 2.7, "time": 1505571851260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.424, 42.5936, 4.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16834332", "mag": 2.5, "time": 1505571656570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.9804, 59.5744, 87.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ap3b", "mag": 5.4, "time": 1505571537070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9072, 16.226, 27.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16860538", "mag": 1.3, "time": 1505570434361, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2424, 62.5449, 91.4 ] } }, +{ "type": "Feature", "properties": { "id": "uw61329766", "mag": 1.85, "time": 1505569264490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.0445, 46.876833, 6.67 ] } }, +{ "type": "Feature", "properties": { "id": "ak16834028", "mag": 1.9, "time": 1505568376976, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.1823, 62.4985, 43.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893206", "mag": 1.29, "time": 1505567825160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.931167, 37.587167, 0.64 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764455", "mag": 2.74, "time": 1505566718480, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.162, 34.381, 19.82 ] } }, +{ "type": "Feature", "properties": { "id": "ak16860534", "mag": 1.8, "time": 1505566502565, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.1816, 59.9775, 117.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893196", "mag": 1.67, "time": 1505566233320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7105, 38.752667, 1.06 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017259001", "mag": 2.53, "time": 1505566066240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.1556, 17.5196, 8.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605483", "mag": 1.9, "time": 1505565978805, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.5538, 38.7481, 7.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764447", "mag": 1.73, "time": 1505565806200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.609667, 33.184833, 2.89 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70235458", "mag": 2.43, "time": 1505565729090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.570167, 37.344833, 5.17 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ap2h", "mag": 5.1, "time": 1505565414430, "felt": null, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 154.9693, -6.4027, 84.07 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893191", "mag": 1.22, "time": 1505565031030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.840833, 37.499667, 1.31 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893176", "mag": 1.02, "time": 1505564232460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.827667, 38.837502, 1.89 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893171", "mag": 1.16, "time": 1505563869000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.124, 36.5485, 6.91 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893166", "mag": 1.98, "time": 1505563826250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.96, 36.383333, 5.84 ] } }, +{ "type": "Feature", "properties": { "id": "ak16860533", "mag": 2.3, "time": 1505563620965, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.2643, 51.2858, 23.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16833723", "mag": 1.8, "time": 1505563033811, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0307, 59.9768, 107.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16833722", "mag": 1.0, "time": 1505562940424, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.5632, 63.5373, 8.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ap1y", "mag": 2.6, "time": 1505562746670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -87.3487, 38.1953, 7.98 ] } }, +{ "type": "Feature", "properties": { "id": "ak16833715", "mag": 1.4, "time": 1505562545553, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0358, 63.0385, 119.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ap1n", "mag": 4.9, "time": 1505561075850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -179.2793, -17.0456, 538.12 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ap1h", "mag": 4.9, "time": 1505561004690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0304, 14.9269, 46.15 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893161", "mag": 1.71, "time": 1505560933840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.120167, 35.9645, 23.92 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at4t", "mag": 4.2, "time": 1505560744440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 128.8254, -7.4355, 134.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16833426", "mag": 1.4, "time": 1505560633966, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.4578, 61.5042, 28.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ap1d", "mag": 2.4, "time": 1505560442800, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -96.8006, 35.9908, 5.836 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893146", "mag": 1.21, "time": 1505560059470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.829167, 37.4595, 2.47 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ap17", "mag": 4.2, "time": 1505558287960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.162, 15.1165, 61.6 ] } }, +{ "type": "Feature", "properties": { "id": "mb80255689", "mag": 1.86, "time": 1505557588190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.1525, 48.101667, 7.53 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893131", "mag": 1.55, "time": 1505557460780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.826, 38.836333, 2.51 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ap0t", "mag": 4.5, "time": 1505557108730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2297, 14.9414, 30.52 ] } }, +{ "type": "Feature", "properties": { "id": "uw61329606", "mag": 1.52, "time": 1505556991880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.998833, 47.691333, 5.06 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ap0r", "mag": 5.4, "time": 1505556693470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 83.5155, 42.2053, 16.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893116", "mag": 1.84, "time": 1505556472360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.136, 35.962667, 25.16 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at4a", "mag": 4.0, "time": 1505555867920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 122.1193, -10.8831, 38.93 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893106", "mag": 2.2, "time": 1505555321940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.918167, 38.061667, 8.48 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764391", "mag": 3.37, "time": 1505555150630, "felt": 12, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.616167, 33.169667, 8.65 ] } }, +{ "type": "Feature", "properties": { "id": "ak16833112", "mag": 1.5, "time": 1505554903991, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.7489, 59.845, 6.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16832833", "mag": 1.9, "time": 1505554129377, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.7145, 60.2604, 9.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16832826", "mag": 1.1, "time": 1505553506665, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3921, 63.5231, 5.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16832818", "mag": 2.0, "time": 1505552113865, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4792, 63.0863, 5.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16860523", "mag": 1.1, "time": 1505550954800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.5868, 63.8926, 99.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ap0a", "mag": 4.0, "time": 1505550836160, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 27.685, 37.0689, 6.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764359", "mag": 1.53, "time": 1505550124480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.9555, 33.145833, 9.49 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764335", "mag": 1.72, "time": 1505549627950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.053167, 36.123167, 1.12 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764327", "mag": 1.0, "time": 1505549298090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.920833, 33.975167, 6.39 ] } }, +{ "type": "Feature", "properties": { "id": "ak16832531", "mag": 1.9, "time": 1505548305568, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.9221, 64.7554, 18.3 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017259000", "mag": 3.64, "time": 1505548231440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -64.0526, 18.4531, 34.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605447", "mag": 1.3, "time": 1505548133652, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.0331, 40.436, 11.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16860520", "mag": 1.3, "time": 1505547550857, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9184, 62.2903, 70.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764303", "mag": 0.95, "time": 1505546199690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.922833, 33.978, 5.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16832252", "mag": 3.1, "time": 1505545940675, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 178.5336, 51.3744, 18.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893051", "mag": 1.0, "time": 1505544999790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8995, 37.518833, 0.05 ] } }, +{ "type": "Feature", "properties": { "id": "hv61909871", "mag": 3.66, "time": 1505544037320, "felt": 734, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.487667, 21.642167, 10.046 ] } }, +{ "type": "Feature", "properties": { "id": "ak16832238", "mag": 2.6, "time": 1505543981141, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.591, 58.4419, 63.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16860517", "mag": 1.9, "time": 1505543962894, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.4461, 59.504, 85.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764247", "mag": 0.97, "time": 1505543854670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.918833, 33.976667, 6.71 ] } }, +{ "type": "Feature", "properties": { "id": "ak16832235", "mag": 1.7, "time": 1505543819625, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.8364, 61.486, 9.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000anze", "mag": 4.4, "time": 1505543417100, "felt": 29, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -90.4791, 13.6017, 52.75 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893026", "mag": 0.96, "time": 1505543269370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8325, 37.540333, 4.97 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893021", "mag": 1.36, "time": 1505543240340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.181833, 37.775667, 14.71 ] } }, +{ "type": "Feature", "properties": { "id": "ak16831965", "mag": 1.2, "time": 1505542824882, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.1125, 62.0856, 43.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893011", "mag": 1.57, "time": 1505541411490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.8025, 38.706667, 3.14 ] } }, +{ "type": "Feature", "properties": { "id": "ak16831959", "mag": 1.0, "time": 1505541221769, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.4333, 66.2529, 10.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16831957", "mag": 1.8, "time": 1505541032598, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.4004, 57.5066, 48.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000anz4", "mag": 4.4, "time": 1505540612950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -60.854, 17.4925, 32.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000anz2", "mag": 4.1, "time": 1505540153920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.143, 15.2335, 36.21 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764183", "mag": 1.57, "time": 1505539498920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.924667, 33.976667, 6.44 ] } }, +{ "type": "Feature", "properties": { "id": "us2000anyv", "mag": 3.7, "time": 1505539256530, "felt": 22, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4153, 42.5716, 8.12 ] } }, +{ "type": "Feature", "properties": { "id": "nc72893001", "mag": 1.74, "time": 1505539200450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.266667, 39.366833, -0.52 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605425", "mag": 1.2, "time": 1505536942149, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.719, 36.6783, 6.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764071", "mag": 3.03, "time": 1505536766220, "felt": 99, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.926333, 33.9745, 5.92 ] } }, +{ "type": "Feature", "properties": { "id": "us2000anyf", "mag": 4.6, "time": 1505535666910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -77.9491, -1.4664, 157.52 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892991", "mag": 1.09, "time": 1505535129720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.777833, 39.807833, 8.29 ] } }, +{ "type": "Feature", "properties": { "id": "us2000any5", "mag": 4.3, "time": 1505534256750, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -89.7094, 13.2544, 54.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16831411", "mag": 1.0, "time": 1505534077361, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.8446, 61.8774, 13.6 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605540", "mag": 1.1, "time": 1505533644071, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.5347, 38.3939, 14.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764039", "mag": 1.68, "time": 1505533494970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.682, 35.141167, 11.28 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764031", "mag": 1.75, "time": 1505533234710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.516833, 32.862, 5.65 ] } }, +{ "type": "Feature", "properties": { "id": "ak16831410", "mag": 1.3, "time": 1505532137489, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.8143, 61.3719, 31.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892971", "mag": 0.98, "time": 1505532054400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8735, 37.542, 7.25 ] } }, +{ "type": "Feature", "properties": { "id": "nm60206921", "mag": 1.9, "time": 1505531769960, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -90.3315, 35.6915, 12.51 ] } }, +{ "type": "Feature", "properties": { "id": "ci37764007", "mag": 1.33, "time": 1505531552680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.105667, 34.034, 6.86 ] } }, +{ "type": "Feature", "properties": { "id": "ak16860509", "mag": 1.7, "time": 1505530441142, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2233, 59.405, 90.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16831409", "mag": 2.6, "time": 1505529914916, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.7519, 54.2192, 117.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763991", "mag": 1.37, "time": 1505528713010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.179, 33.193833, 7.41 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763983", "mag": 1.44, "time": 1505528615710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.793333, 33.493667, 4.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000anxt", "mag": 4.3, "time": 1505528560360, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -100.0309, 17.2785, 69.28 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892956", "mag": 1.06, "time": 1505527887720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.904167, 37.519667, -0.32 ] } }, +{ "type": "Feature", "properties": { "id": "ak16831144", "mag": 1.1, "time": 1505526547318, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6449, 63.5861, 5.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16831140", "mag": 1.8, "time": 1505526295378, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.4346, 59.0192, 66.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892946", "mag": 1.02, "time": 1505525854460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.764168, 38.786999, 0.87 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763959", "mag": 1.17, "time": 1505525787900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.395167, 34.877167, 11.59 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892941", "mag": 1.34, "time": 1505525721400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.772833, 38.807167, -0.11 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892936", "mag": 1.51, "time": 1505525691180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.819167, 37.545, 3.75 ] } }, +{ "type": "Feature", "properties": { "id": "us2000anxl", "mag": 4.6, "time": 1505525689580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -170.5872, 52.0486, 37.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16831132", "mag": 1.8, "time": 1505525666712, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6913, 63.5749, 10.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16831131", "mag": 1.1, "time": 1505525600973, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6368, 63.6017, 8.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892931", "mag": 1.16, "time": 1505524996900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.806167, 36.224833, 7.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830868", "mag": 2.0, "time": 1505523996780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.276, 57.4142, 39.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16860501", "mag": 1.8, "time": 1505523576256, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.099, 59.7523, 100.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830864", "mag": 1.0, "time": 1505522724047, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -142.3705, 66.2593, 7.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830862", "mag": 1.4, "time": 1505522720015, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8357, 63.5631, 6.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at41", "mag": 4.6, "time": 1505522674060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 69.6259, -23.9788, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000anwt", "mag": 4.3, "time": 1505522470090, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -74.2357, -37.2039, 9.72 ] } }, +{ "type": "Feature", "properties": { "id": "uu60246252", "mag": 1.18, "time": 1505521902190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4075, 42.596, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830861", "mag": 1.2, "time": 1505521740882, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.7991, 61.6212, 38.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830860", "mag": 1.0, "time": 1505521253411, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.9628, 64.7584, 4.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830858", "mag": 1.6, "time": 1505521010086, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.3459, 62.5868, 57.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000at4p", "mag": 4.6, "time": 1505520028160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -30.9669, 2.8319, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830852", "mag": 2.5, "time": 1505519615949, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.8797, 64.7729, 8.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830848", "mag": 3.4, "time": 1505519352423, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.9613, 56.0051, 45.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830585", "mag": 2.2, "time": 1505518242769, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.9245, 64.7851, 9.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830502", "mag": 1.5, "time": 1505517724005, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.3927, 62.7723, 62.1 ] } }, +{ "type": "Feature", "properties": { "id": "hv61909476", "mag": 1.46, "time": 1505517626230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.6105, 19.420833, 2.212 ] } }, +{ "type": "Feature", "properties": { "id": "us2000anvi", "mag": 4.9, "time": 1505517194700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 142.9781, 67.621, 14.89 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852972", "mag": 2.3, "time": 1505516822454, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -175.046, 51.6929, 12.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asms", "mag": 4.2, "time": 1505515397660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 151.5667, -4.6769, 135.04 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830490", "mag": 2.1, "time": 1505515348546, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2666, 60.2335, 149.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000anza", "mag": 4.2, "time": 1505515078190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 91.9514, 12.8959, 27.42 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852968", "mag": 1.7, "time": 1505514517165, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.1028, 59.5574, 89.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830486", "mag": 1.5, "time": 1505514413181, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.8103, 64.7863, 4.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852966", "mag": 1.7, "time": 1505514284700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.1862, 59.9258, 120.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892896", "mag": 1.71, "time": 1505514238180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.848, 40.281, 4.76 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqg1", "mag": 3.2, "time": 1505514207940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.4161, 53.6697, 25.19 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892891", "mag": 1.42, "time": 1505514193630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7085, 38.747, 1.29 ] } }, +{ "type": "Feature", "properties": { "id": "us2000antx", "mag": 2.8, "time": 1505513431240, "felt": 6, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.9688, 37.279, 4.85 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830471", "mag": 1.3, "time": 1505513126878, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.0818, 58.2131, 3.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqg0", "mag": 2.6, "time": 1505512544140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 178.6723, 51.5577, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000antf", "mag": 4.6, "time": 1505512126220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 147.5618, -5.9077, 108.71 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830466", "mag": 1.7, "time": 1505511266504, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -138.7109, 60.4891, 8.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asmu", "mag": 4.3, "time": 1505510611600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 137.0445, 34.5022, 328.82 ] } }, +{ "type": "Feature", "properties": { "id": "us2000anrz", "mag": 3.1, "time": 1505510517900, "felt": 6, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4379, 42.6057, 6.23 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830211", "mag": 3.0, "time": 1505510263990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.8926, 64.7765, 8.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852960", "mag": 1.5, "time": 1505509916511, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1722, 61.1116, 68.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852959", "mag": 2.0, "time": 1505509441508, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4835, 51.7117, 13.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892861", "mag": 1.56, "time": 1505509197990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.217167, 35.152667, 7.27 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605401", "mag": 1.3, "time": 1505508712532, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.5746, 38.7781, 10.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000anqp", "mag": 4.4, "time": 1505508340380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 142.6832, 12.6788, 125.94 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605391", "mag": 1.0, "time": 1505508003630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.3614, 38.5819, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763831", "mag": 1.45, "time": 1505507271630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.356667, 34.4865, 9.29 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830197", "mag": 2.1, "time": 1505507006348, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.8768, 60.2433, 18.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892846", "mag": 2.43, "time": 1505506978320, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.075333, 36.496667, 4.87 ] } }, +{ "type": "Feature", "properties": { "id": "us2000annp", "mag": 2.3, "time": 1505506905940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4277, 42.5599, 9.59 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829946", "mag": 2.6, "time": 1505506584731, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.9781, 57.0654, 81.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892841", "mag": 1.21, "time": 1505506558180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.801833, 38.823167, 2.59 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763815", "mag": 1.6, "time": 1505506434580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.772667, 33.326167, 12.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829942", "mag": 2.0, "time": 1505506388550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.6381, 59.7681, 10.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829939", "mag": 1.3, "time": 1505506296730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3557, 64.9805, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829919", "mag": 3.2, "time": 1505506091028, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.8331, 59.8732, 91.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829917", "mag": 1.1, "time": 1505506034459, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.1896, 63.4641, 20.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892821", "mag": 1.26, "time": 1505506033580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.407667, 37.504333, 1.03 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017258005", "mag": 3.43, "time": 1505505501670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -64.6295, 19.1915, 40.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829915", "mag": 1.5, "time": 1505505395135, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6711, 60.3885, 41.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829913", "mag": 2.1, "time": 1505505235226, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -135.0254, 58.4988, 9.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829904", "mag": 1.1, "time": 1505503708373, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.5162, 63.4918, 1.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892806", "mag": 1.03, "time": 1505503474580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.488333, 37.450833, 4.91 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763759", "mag": 1.72, "time": 1505502131450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.796, 33.503167, 6.45 ] } }, +{ "type": "Feature", "properties": { "id": "us2000anjp", "mag": 5.5, "time": 1505501282460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -28.3292, -55.4644, 9.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892771", "mag": 1.05, "time": 1505500911720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.725334, 38.757, 1.52 ] } }, +{ "type": "Feature", "properties": { "id": "us2000anjh", "mag": 4.5, "time": 1505500904740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 169.72, 54.0122, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "uw61308057", "mag": 0.97, "time": 1505500854880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -124.858667, 48.515, 37.88 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829625", "mag": 1.6, "time": 1505499922143, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3749, 60.4419, 18.3 ] } }, +{ "type": "Feature", "properties": { "id": "uu60246132", "mag": 1.51, "time": 1505499901840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.420667, 42.537167, 7.15 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892766", "mag": 2.33, "time": 1505499839660, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.49, 37.447667, 5.54 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892756", "mag": 1.0, "time": 1505499395080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.799667, 37.462333, 0.05 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892761", "mag": 1.02, "time": 1505499284680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.445, 37.379333, 14.57 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829622", "mag": 1.1, "time": 1505498936272, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.4458, 61.0059, 4.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000anhz", "mag": 4.2, "time": 1505498539950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.9892, 15.1825, 46.32 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829378", "mag": 1.9, "time": 1505498347271, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -138.7292, 60.4845, 7.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763719", "mag": 1.44, "time": 1505498108300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.178169, 35.602833, 5.95 ] } }, +{ "type": "Feature", "properties": { "id": "us2000anhd", "mag": 5.0, "time": 1505497546880, "felt": 12, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 28.8132, -2.7314, 12.98 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763711", "mag": 1.02, "time": 1505497385540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.102833, 33.170333, 9.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829370", "mag": 1.8, "time": 1505496661795, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.3298, 60.0961, 93.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892746", "mag": 1.22, "time": 1505496479100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.641667, 37.477167, 6.06 ] } }, +{ "type": "Feature", "properties": { "id": "us2000angr", "mag": 4.6, "time": 1505496373980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 160.527, 53.8618, 60.06 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763679", "mag": 1.04, "time": 1505495567950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.808, 36.012167, 1.77 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829365", "mag": 1.4, "time": 1505494067842, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.3827, 63.102, 108.2 ] } }, +{ "type": "Feature", "properties": { "id": "uw61308032", "mag": 1.41, "time": 1505493000220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.048333, 47.3965, 13.93 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892711", "mag": 1.1, "time": 1505492830650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.807, 38.822667, 2.57 ] } }, +{ "type": "Feature", "properties": { "id": "uw61308027", "mag": 1.17, "time": 1505492391290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.0485, 47.395833, 13.68 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829360", "mag": 2.9, "time": 1505491697051, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.4354, 53.7237, 49.7 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017258004", "mag": 1.98, "time": 1505491060700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -66.7353, 18.0013, 7.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829358", "mag": 1.6, "time": 1505491027770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6843, 60.3013, 49.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000angc", "mag": 4.7, "time": 1505490910540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 140.4948, -51.951, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829355", "mag": 3.2, "time": 1505490508935, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -162.4074, 55.3684, 134.2 ] } }, +{ "type": "Feature", "properties": { "id": "uu60246117", "mag": 1.78, "time": 1505490038910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.438833, 42.587833, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763607", "mag": 1.3, "time": 1505489472220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.491167, 33.8525, -0.5 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70235413", "mag": 2.08, "time": 1505488486050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.96, 37.276667, 2.46 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829351", "mag": 1.4, "time": 1505488175090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4615, 63.0908, 2.8 ] } }, +{ "type": "Feature", "properties": { "id": "hv61908956", "mag": 2.13, "time": 1505487142110, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.862333, 19.450333, 1.074 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829348", "mag": 2.3, "time": 1505486994801, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -163.5994, 64.2424, 10.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852936", "mag": 1.5, "time": 1505485797408, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5105, 60.533, 54.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829346", "mag": 1.6, "time": 1505485726963, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.8399, 59.9528, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80255559", "mag": 1.54, "time": 1505485070000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.528, 46.898, 12.92 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asmd", "mag": 4.0, "time": 1505484479350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 118.2763, -7.0257, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763559", "mag": 1.43, "time": 1505483064830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.6045, 33.127833, 7.81 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763535", "mag": 1.14, "time": 1505482307640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.736833, 33.222833, 12.21 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763527", "mag": 1.65, "time": 1505482113260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.742833, 33.223833, 11.67 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763511", "mag": 2.98, "time": 1505481739410, "felt": 62, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.750167, 33.221833, 11.54 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605319", "mag": 1.4, "time": 1505481612897, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.536, 39.4025, 7.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829343", "mag": 1.1, "time": 1505481511288, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -138.734, 60.477, 7.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829342", "mag": 1.1, "time": 1505481115042, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -138.6866, 60.4978, 7.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000an8y", "mag": 3.0, "time": 1505480692500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.9665, 37.2798, 4.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aqfs", "mag": 4.0, "time": 1505480677660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 177.1015, 51.6899, 62.37 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892656", "mag": 1.2, "time": 1505479917850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.478833, 36.923833, 5.96 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852930", "mag": 2.2, "time": 1505479857860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.6735, 54.2139, 72.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852929", "mag": 1.3, "time": 1505479424949, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8074, 61.6789, 63.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763455", "mag": 1.43, "time": 1505479133890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.172833, 33.1885, 5.98 ] } }, +{ "type": "Feature", "properties": { "id": "us2000an8s", "mag": 5.0, "time": 1505479021440, "felt": null, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 99.4856, 1.5915, 160.08 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852928", "mag": 2.1, "time": 1505478896521, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 178.6795, 51.3691, 28.0 ] } }, +{ "type": "Feature", "properties": { "id": "uw61307972", "mag": 0.95, "time": 1505478878910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.588, 45.973333, 13.92 ] } }, +{ "type": "Feature", "properties": { "id": "mb80255544", "mag": 1.19, "time": 1505478239910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.527, 46.868167, 11.01 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852925", "mag": 2.1, "time": 1505477897255, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -160.3237, 54.8499, 18.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892641", "mag": 1.01, "time": 1505477523520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.799667, 38.833832, 2.01 ] } }, +{ "type": "Feature", "properties": { "id": "us2000an8e", "mag": 2.7, "time": 1505477274970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.525, 46.8611, 10.18 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852924", "mag": 1.4, "time": 1505476792218, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.5946, 57.6534, 29.9 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017258003", "mag": 2.18, "time": 1505476739060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -66.7808, 18.0135, 13.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852923", "mag": 2.0, "time": 1505476493650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -160.7994, 54.9781, 25.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000an7z", "mag": 3.8, "time": 1505475906360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -161.753, 54.3697, 28.05 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892636", "mag": 2.0, "time": 1505475684320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.723167, 38.750667, 1.87 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829087", "mag": 1.6, "time": 1505475033163, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.6709, 67.7999, 2.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829082", "mag": 1.8, "time": 1505474984470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9722, 63.0999, 131.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16829079", "mag": 1.4, "time": 1505474678706, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -138.7297, 60.4779, 8.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000an7j", "mag": 2.7, "time": 1505474631800, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4441, 42.568, 7.22 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892626", "mag": 1.04, "time": 1505474439810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.804667, 37.458833, 0.13 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763407", "mag": 3.23, "time": 1505473976550, "felt": 13, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.303167, 35.032833, 11.48 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605300", "mag": 1.1, "time": 1505473795002, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.7828, 38.6088, 8.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16828841", "mag": 1.7, "time": 1505473634732, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.54, 59.9657, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "uw61307932", "mag": 1.91, "time": 1505473610560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.044333, 46.870333, 5.23 ] } }, +{ "type": "Feature", "properties": { "id": "uw61307927", "mag": 2.04, "time": 1505473528440, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.040667, 46.874167, 5.89 ] } }, +{ "type": "Feature", "properties": { "id": "us2000an74", "mag": 4.6, "time": 1505473111350, "felt": 7, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -60.5703, 14.9752, 55.34 ] } }, +{ "type": "Feature", "properties": { "id": "ak16828838", "mag": 2.3, "time": 1505473096912, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.7454, 57.1664, 7.6 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70235273", "mag": 1.73, "time": 1505472377400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.7775, 37.328833, 5.95 ] } }, +{ "type": "Feature", "properties": { "id": "ak16828836", "mag": 1.2, "time": 1505472358115, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.0141, 62.1581, 7.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000an6x", "mag": 3.0, "time": 1505471961060, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4507, 42.5991, 6.39 ] } }, +{ "type": "Feature", "properties": { "id": "ak16828834", "mag": 1.6, "time": 1505471035679, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.5654, 60.6122, 4.1 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017258002", "mag": 3.3, "time": 1505471012430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -65.039, 18.7165, 49.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892606", "mag": 2.13, "time": 1505469780960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.106167, 36.291833, 27.69 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852912", "mag": 1.9, "time": 1505469324601, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0438, 60.2245, 124.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16828830", "mag": 2.7, "time": 1505468486908, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.378, 53.6654, 25.8 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017258001", "mag": 3.31, "time": 1505468158660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.9741, 18.1111, 53.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16828827", "mag": 1.9, "time": 1505468029663, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.1086, 60.3742, 87.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000an6e", "mag": 2.1, "time": 1505467401730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4369, 42.5723, 4.71 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763367", "mag": 1.32, "time": 1505466931820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.601167, 35.792, 0.88 ] } }, +{ "type": "Feature", "properties": { "id": "hv61908811", "mag": 1.86, "time": 1505466749280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.473328, 19.201, 34.94 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017258000", "mag": 2.64, "time": 1505466025100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -66.746, 17.9996, 11.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000an5j", "mag": 3.6, "time": 1505463761200, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4416, 42.5753, 5.34 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852908", "mag": 1.3, "time": 1505463469458, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.2829, 57.3488, 39.2 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605283", "mag": 1.7, "time": 1505461873940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.4437, 37.5652, 30.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892591", "mag": 2.34, "time": 1505461865770, "felt": 34, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.815833, 37.416, -0.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892576", "mag": 1.69, "time": 1505460536470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.027667, 35.933167, 12.08 ] } }, +{ "type": "Feature", "properties": { "id": "ak16828820", "mag": 1.4, "time": 1505460317106, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.3735, 59.7943, 6.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852903", "mag": 1.3, "time": 1505459205027, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.8448, 60.0925, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16828585", "mag": 1.4, "time": 1505458631465, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.0593, 61.7131, 3.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000an4v", "mag": 4.4, "time": 1505458308660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 179.5767, -21.9172, 640.49 ] } }, +{ "type": "Feature", "properties": { "id": "ak16828584", "mag": 1.4, "time": 1505458006745, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.7132, 60.0014, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16828563", "mag": 2.8, "time": 1505456528325, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.4989, 60.1125, 151.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16828570", "mag": 2.5, "time": 1505456526893, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2519, 60.1326, 152.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892551", "mag": 2.6, "time": 1505456369610, "felt": 148, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.814333, 37.412167, -0.14 ] } }, +{ "type": "Feature", "properties": { "id": "ak16828560", "mag": 1.1, "time": 1505456105481, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.0298, 65.3407, 11.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763319", "mag": 1.07, "time": 1505455402480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.7685, 33.327833, 13.39 ] } }, +{ "type": "Feature", "properties": { "id": "ak16828558", "mag": 1.4, "time": 1505455356648, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.3726, 61.4994, 31.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852896", "mag": 1.9, "time": 1505455322292, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2513, 60.1603, 135.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892546", "mag": 1.03, "time": 1505455248140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.810667, 38.83, 2.09 ] } }, +{ "type": "Feature", "properties": { "id": "ak16828556", "mag": 1.6, "time": 1505455168783, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.9297, 60.9306, 19.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763311", "mag": 1.21, "time": 1505454701910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.190167, 33.332667, 10.93 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852894", "mag": 1.7, "time": 1505453971264, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.8667, 60.0997, 103.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000an3z", "mag": 4.6, "time": 1505453216820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -82.4676, -42.4862, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852893", "mag": 1.1, "time": 1505452792257, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.4902, 57.7349, 15.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16828554", "mag": 1.4, "time": 1505452679971, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.3948, 61.1147, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852891", "mag": 1.6, "time": 1505451604059, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.9039, 61.8273, 105.7 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70235253", "mag": 1.62, "time": 1505451601330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.7765, 37.333333, 5.53 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892536", "mag": 2.78, "time": 1505451572070, "felt": 348, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.804667, 37.415, 2.65 ] } }, +{ "type": "Feature", "properties": { "id": "ak16828322", "mag": 1.1, "time": 1505451186525, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -138.7346, 60.4761, 9.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000anyw", "mag": 2.0, "time": 1505450267000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -71.42, 45.73, 18.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892526", "mag": 1.26, "time": 1505449157230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.802333, 38.8245, 1.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16828321", "mag": 1.4, "time": 1505448965816, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.0369, 60.3155, 0.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000an31", "mag": 4.3, "time": 1505448638800, "felt": 9, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -76.4066, -11.9189, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80255479", "mag": 1.23, "time": 1505447369570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.529333, 46.896667, 13.22 ] } }, +{ "type": "Feature", "properties": { "id": "ak16828316", "mag": 2.0, "time": 1505447351856, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.1687, 59.8152, 101.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16828314", "mag": 1.7, "time": 1505447232655, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.4451, 60.022, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892516", "mag": 1.1, "time": 1505446837720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.730835, 38.793999, 1.32 ] } }, +{ "type": "Feature", "properties": { "id": "uu60245937", "mag": 2.38, "time": 1505446750290, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -108.831833, 40.139667, 5.96 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605251", "mag": 1.0, "time": 1505446468632, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9033, 38.4011, 9.6 ] } }, +{ "type": "Feature", "properties": { "id": "uw61307757", "mag": 1.87, "time": 1505444885110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.039, 46.879667, 6.38 ] } }, +{ "type": "Feature", "properties": { "id": "ak16828311", "mag": 1.7, "time": 1505444727120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -142.9607, 69.4522, 5.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16828309", "mag": 1.6, "time": 1505444714123, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.2585, 60.8639, 35.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16828078", "mag": 1.7, "time": 1505444473211, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.9441, 60.8403, 88.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16852882", "mag": 1.6, "time": 1505443841428, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.2335, 53.7145, 69.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000an1z", "mag": 4.4, "time": 1505443535780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.5573, 15.2748, 63.05 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892506", "mag": 1.02, "time": 1505442684550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.883667, 37.553, 2.17 ] } }, +{ "type": "Feature", "properties": { "id": "hv61908531", "mag": 3.04, "time": 1505439944520, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.466833, 19.197667, 35.437 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827839", "mag": 1.5, "time": 1505439822541, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.4032, 62.4253, 2.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763231", "mag": 1.55, "time": 1505439516220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.3195, 34.068167, 18.36 ] } }, +{ "type": "Feature", "properties": { "id": "us2000an15", "mag": 5.2, "time": 1505439500860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5689, -26.6333, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000an0z", "mag": 4.8, "time": 1505439407990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 94.866, 18.8304, 42.15 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892491", "mag": 1.99, "time": 1505438838520, "felt": 6, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.813833, 37.412167, -0.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892486", "mag": 3.28, "time": 1505438267780, "felt": 1110, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.805667, 37.414, -0.21 ] } }, +{ "type": "Feature", "properties": { "id": "uw61307737", "mag": 1.35, "time": 1505438193040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.260833, 45.950833, -0.29 ] } }, +{ "type": "Feature", "properties": { "id": "us2000an0d", "mag": 2.7, "time": 1505437987460, "felt": 5, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.5868, 37.2136, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000an0g", "mag": 4.3, "time": 1505437868680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4079, 15.6978, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827837", "mag": 1.3, "time": 1505437000881, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.7, 64.3159, 3.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aslu", "mag": 4.1, "time": 1505436496140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.8507, -18.1469, 603.85 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763199", "mag": 1.36, "time": 1505435921800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.729667, 33.651667, 14.16 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892481", "mag": 1.05, "time": 1505435403940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.1895, 36.589667, 2.71 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aslz", "mag": 4.4, "time": 1505434827610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 141.716, 24.4725, 93.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amzk", "mag": 4.1, "time": 1505434054870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.3134, -31.912, 136.67 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827738", "mag": 1.1, "time": 1505433675781, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.4097, 60.0357, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "uw61307717", "mag": 1.13, "time": 1505433139350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.677167, 47.835167, -0.74 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892476", "mag": 1.21, "time": 1505432696710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.828167, 37.448333, 11.34 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827737", "mag": 2.4, "time": 1505432573787, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -163.6213, 54.0704, 37.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amz3", "mag": 4.1, "time": 1505431969130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.671, 15.2225, 53.79 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892471", "mag": 1.5, "time": 1505431533120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.4815, 38.607167, 11.47 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892466", "mag": 1.83, "time": 1505431346810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.8125, 37.417833, 0.06 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827381", "mag": 2.1, "time": 1505430963793, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5301, 63.0381, 100.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amyn", "mag": 4.7, "time": 1505430410000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -172.7418, -15.3348, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892451", "mag": 1.34, "time": 1505430316610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.842333, 38.821, 2.01 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827378", "mag": 1.7, "time": 1505430242693, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.6605, 59.9169, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827376", "mag": 1.4, "time": 1505430223593, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3686, 64.993, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70235238", "mag": 1.58, "time": 1505429674020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.887667, 37.203667, 6.13 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827373", "mag": 1.9, "time": 1505429324646, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.3648, 60.031, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827371", "mag": 1.2, "time": 1505429076761, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.7478, 61.0185, 13.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amx5", "mag": 4.0, "time": 1505428206900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.2168, 15.3544, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892426", "mag": 2.04, "time": 1505428077100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.454833, 37.434333, 10.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16861216", "mag": 1.9, "time": 1505427925219, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -158.0714, 56.1589, 10.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827036", "mag": 2.0, "time": 1505427923919, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.0766, 61.1472, 0.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amww", "mag": 5.2, "time": 1505427661920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 170.1022, -13.8345, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763135", "mag": 1.49, "time": 1505427523820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.866, 34.011167, 16.92 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605229", "mag": 2.2, "time": 1505427385689, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.0155, 38.8648, 4.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000askz", "mag": 4.1, "time": 1505426291450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 129.1685, -7.2026, 147.79 ] } }, +{ "type": "Feature", "properties": { "id": "hv61908231", "mag": 2.43, "time": 1505426012270, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.012665, 19.708, 2.82 ] } }, +{ "type": "Feature", "properties": { "id": "uu60245817", "mag": 1.37, "time": 1505425437900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.738, 38.746667, 7.72 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827032", "mag": 1.7, "time": 1505425052822, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.4453, 59.9712, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827035", "mag": 2.3, "time": 1505424622002, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.6154, 53.6195, 25.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asl6", "mag": 4.4, "time": 1505424366710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 122.1651, -12.9278, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017257005", "mag": 3.03, "time": 1505423754820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.8618, 18.9605, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amub", "mag": 2.8, "time": 1505423589100, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.1847, 37.3761, 9.38 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892386", "mag": 1.71, "time": 1505423524180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.993, 37.849, 7.27 ] } }, +{ "type": "Feature", "properties": { "id": "uw61307597", "mag": 1.91, "time": 1505423420600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.516333, 49.4855, -1.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827021", "mag": 2.6, "time": 1505422812693, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.9235, 64.0866, 5.1 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017257004", "mag": 3.1, "time": 1505421809880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.5351, 18.7848, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "uw61307587", "mag": 2.41, "time": 1505421654690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.038167, 46.8785, 6.64 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763103", "mag": 1.09, "time": 1505421634220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.484667, 33.852667, -0.55 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763095", "mag": 2.06, "time": 1505421264070, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.377, 34.075, 2.89 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763087", "mag": 1.19, "time": 1505421203990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.9245, 33.981667, 6.59 ] } }, +{ "type": "Feature", "properties": { "id": "uw61307577", "mag": 2.03, "time": 1505420251860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.041833, 46.875667, 6.94 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763071", "mag": 1.01, "time": 1505420033530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.481, 33.8295, -0.53 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amr0", "mag": 3.2, "time": 1505419914220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -103.2947, 31.1684, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16826805", "mag": 1.7, "time": 1505419715229, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.541, 59.9804, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80255399", "mag": 3.06, "time": 1505419221280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.5865, 48.5185, 11.24 ] } }, +{ "type": "Feature", "properties": { "id": "uu60245777", "mag": 2.41, "time": 1505419186750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -108.829333, 40.126, 5.93 ] } }, +{ "type": "Feature", "properties": { "id": "ak16826800", "mag": 1.6, "time": 1505419140835, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.9798, 59.9221, 1.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892321", "mag": 1.03, "time": 1505418518980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.838833, 37.542333, 4.28 ] } }, +{ "type": "Feature", "properties": { "id": "ak16861208", "mag": 1.9, "time": 1505418243673, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0345, 59.5576, 91.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892316", "mag": 1.93, "time": 1505418215210, "felt": 0, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.825833, 37.479167, 0.95 ] } }, +{ "type": "Feature", "properties": { "id": "uw61307562", "mag": 1.61, "time": 1505417734660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.201667, 47.657667, 24.36 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892311", "mag": 2.58, "time": 1505417475310, "felt": 83, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.815167, 37.412167, -0.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16826593", "mag": 3.3, "time": 1505417123986, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -162.9114, 52.3919, 7.2 ] } }, +{ "type": "Feature", "properties": { "id": "ld60143041", "mag": 1.13, "time": 1505416429790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -78.886167, 43.172167, 4.49 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amnb", "mag": 3.0, "time": 1505416249190, "felt": 10, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.5193, 36.2853, 5.18 ] } }, +{ "type": "Feature", "properties": { "id": "ak16826590", "mag": 1.5, "time": 1505416113279, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1135, 61.6397, 76.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16826581", "mag": 3.0, "time": 1505415978301, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.7549, 53.141, 25.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16826576", "mag": 2.1, "time": 1505415492270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.9009, 60.0386, 108.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16826575", "mag": 1.4, "time": 1505414640813, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.4567, 60.0012, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892281", "mag": 1.22, "time": 1505414516760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.106667, 37.328833, -0.31 ] } }, +{ "type": "Feature", "properties": { "id": "ak16826369", "mag": 1.5, "time": 1505413533625, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.2439, 60.5671, 11.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16826365", "mag": 2.1, "time": 1505413453164, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.2344, 60.5666, 13.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16826364", "mag": 1.2, "time": 1505413265164, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.6599, 59.9119, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37763023", "mag": 1.39, "time": 1505413136790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.316167, 35.0525, -0.97 ] } }, +{ "type": "Feature", "properties": { "id": "uw61307532", "mag": 1.1, "time": 1505412859730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.3855, 45.629833, -1.63 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892266", "mag": 0.96, "time": 1505412496280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.823167, 37.5355, 0.22 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892261", "mag": 1.1, "time": 1505411783250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.808166, 38.800167, 2.65 ] } }, +{ "type": "Feature", "properties": { "id": "ak16826335", "mag": 1.2, "time": 1505411310289, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.0556, 61.0558, 10.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16826330", "mag": 1.6, "time": 1505411005327, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8642, 60.9198, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amk5", "mag": 5.8, "time": 1505410888670, "felt": 9, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 145.732, 18.6699, 173.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892241", "mag": 3.28, "time": 1505410337330, "felt": 1346, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.8135, 37.411667, -0.21 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amw9", "mag": 2.9, "time": 1505410106220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.434, 42.5971, 8.27 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762975", "mag": 1.37, "time": 1505410085790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.795333, 33.494833, 5.03 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amja", "mag": 3.2, "time": 1505409999020, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4403, 42.586, 8.7 ] } }, +{ "type": "Feature", "properties": { "id": "uw61307502", "mag": 2.03, "time": 1505409449050, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.775333, 47.590667, 26.27 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amis", "mag": 4.1, "time": 1505408885650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.3313, 15.7247, 66.16 ] } }, +{ "type": "Feature", "properties": { "id": "ak16826120", "mag": 2.2, "time": 1505408670072, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.8183, 60.7702, 77.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amhu", "mag": 2.5, "time": 1505407539000, "felt": 179, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.0236, 32.7967, 6.19 ] } }, +{ "type": "Feature", "properties": { "id": "ak16826109", "mag": 3.4, "time": 1505406315703, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.9733, 53.4109, 37.9 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017257003", "mag": 1.93, "time": 1505405250720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.1335, 18.0533, 14.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16825909", "mag": 3.0, "time": 1505405033445, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.4291, 57.7254, 15.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16861191", "mag": 2.2, "time": 1505404726740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -168.4598, 52.5561, 41.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amga", "mag": 4.5, "time": 1505404343560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 147.122, -6.0228, 63.06 ] } }, +{ "type": "Feature", "properties": { "id": "uu60245622", "mag": 1.46, "time": 1505403828660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.640167, 41.675, 10.23 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762935", "mag": 1.53, "time": 1505403471570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.7005, 36.071833, 0.62 ] } }, +{ "type": "Feature", "properties": { "id": "ak16861190", "mag": 1.9, "time": 1505403359391, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.3367, 58.804, 116.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762927", "mag": 1.08, "time": 1505403357540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.6365, 33.9595, 15.51 ] } }, +{ "type": "Feature", "properties": { "id": "ak16825908", "mag": 1.4, "time": 1505402885768, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.5012, 61.3116, 5.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16825714", "mag": 2.2, "time": 1505399922942, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.5211, 53.4862, 2.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892201", "mag": 2.8, "time": 1505399703490, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8115, 37.473, 1.65 ] } }, +{ "type": "Feature", "properties": { "id": "ak16825708", "mag": 2.5, "time": 1505399664156, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.3242, 59.9299, 129.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amdz", "mag": 4.3, "time": 1505399623950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.8439, 15.4623, 51.01 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70235213", "mag": 2.12, "time": 1505398747570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.888167, 37.203167, 5.99 ] } }, +{ "type": "Feature", "properties": { "id": "ak16825704", "mag": 1.0, "time": 1505398436381, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.6928, 63.8584, 11.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762895", "mag": 1.82, "time": 1505398376370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.448167, 33.465, 11.86 ] } }, +{ "type": "Feature", "properties": { "id": "mb80255329", "mag": 1.87, "time": 1505398289770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.534833, 46.870333, 11.87 ] } }, +{ "type": "Feature", "properties": { "id": "ak16825519", "mag": 1.8, "time": 1505397944345, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.464, 59.9879, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amcx", "mag": 2.4, "time": 1505397840240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4117, 42.6047, 6.9 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017257002", "mag": 3.32, "time": 1505397292070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -68.3985, 17.9023, 89.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16861180", "mag": 2.0, "time": 1505397099289, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.7867, 53.5505, 48.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16861178", "mag": 1.1, "time": 1505394745904, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.8149, 59.8173, 16.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892181", "mag": 0.97, "time": 1505394542400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.833667, 37.603833, 3.53 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605167", "mag": 1.1, "time": 1505394484720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9328, 38.4065, 6.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16825327", "mag": 1.8, "time": 1505394377057, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.5142, 60.0065, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16825325", "mag": 1.1, "time": 1505393895767, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.0247, 61.1655, 6.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16825323", "mag": 1.3, "time": 1505393727514, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.0737, 61.1407, 3.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ambm", "mag": 2.8, "time": 1505393579230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4339, 42.5276, 8.74 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892176", "mag": 1.12, "time": 1505393008100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8295, 37.486167, 1.89 ] } }, +{ "type": "Feature", "properties": { "id": "ak16825308", "mag": 2.8, "time": 1505392115017, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.1037, 58.6121, 140.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892171", "mag": 1.95, "time": 1505392014690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.811, 37.47, 1.05 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762879", "mag": 2.48, "time": 1505391903440, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.03, 34.269167, 1.91 ] } }, +{ "type": "Feature", "properties": { "id": "hv61907846", "mag": 1.74, "time": 1505391154930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.801498, 20.135166, 20.69 ] } }, +{ "type": "Feature", "properties": { "id": "ak16825129", "mag": 1.8, "time": 1505390600450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.6941, 53.4145, 21.6 ] } }, +{ "type": "Feature", "properties": { "id": "uu60245547", "mag": 1.86, "time": 1505390326640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.506167, 37.5615, 15.73 ] } }, +{ "type": "Feature", "properties": { "id": "ak16825126", "mag": 1.4, "time": 1505389290941, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.5082, 60.1407, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16825125", "mag": 1.0, "time": 1505389269829, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.3654, 61.4964, 18.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16861166", "mag": 1.9, "time": 1505388913353, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.3862, 51.6162, 20.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16825120", "mag": 2.1, "time": 1505388602725, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -159.7931, 54.8482, 3.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16825116", "mag": 1.5, "time": 1505388522841, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.3442, 61.3489, 49.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16825115", "mag": 1.2, "time": 1505388281614, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.5528, 61.7241, 28.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16824940", "mag": 1.2, "time": 1505387093135, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.3758, 61.1701, 24.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892141", "mag": 1.22, "time": 1505386514410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.131, 36.571833, 9.94 ] } }, +{ "type": "Feature", "properties": { "id": "ak16824937", "mag": 2.5, "time": 1505385684936, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -168.0082, 52.3291, 6.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16824932", "mag": 1.6, "time": 1505384400903, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.5379, 59.9886, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16824930", "mag": 1.2, "time": 1505383839558, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -144.3238, 66.4782, 11.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16861154", "mag": 1.9, "time": 1505383026342, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.851, 54.0129, 69.5 ] } }, +{ "type": "Feature", "properties": { "id": "hv61907791", "mag": 1.61, "time": 1505382391650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.223667, 18.879, 14.409 ] } }, +{ "type": "Feature", "properties": { "id": "ak16824762", "mag": 1.4, "time": 1505381878343, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4212, 60.1553, 64.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16824759", "mag": 2.0, "time": 1505381875397, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7269, 61.5265, 60.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892131", "mag": 0.97, "time": 1505381710130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.720001, 38.778168, 1.63 ] } }, +{ "type": "Feature", "properties": { "id": "ak16824756", "mag": 2.0, "time": 1505380861272, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.0471, 60.1915, 70.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16861150", "mag": 2.6, "time": 1505380391671, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -162.8518, 53.4455, 2.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16824753", "mag": 2.6, "time": 1505380263376, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -158.1582, 56.2796, 14.2 ] } }, +{ "type": "Feature", "properties": { "id": "uu60245457", "mag": 2.53, "time": 1505379272870, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -108.827333, 40.120667, -3.25 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762823", "mag": 2.96, "time": 1505378281630, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.181833, 31.831667, 18.32 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892121", "mag": 1.02, "time": 1505377845780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.717499, 38.774666, 2.13 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892116", "mag": 1.11, "time": 1505377833950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.714333, 38.776667, 1.68 ] } }, +{ "type": "Feature", "properties": { "id": "us2000am81", "mag": 4.6, "time": 1505377166860, "felt": 66, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -76.4481, -11.977, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70235208", "mag": 1.81, "time": 1505376928150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.570333, 37.345667, 5.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16824583", "mag": 1.6, "time": 1505376729312, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.4585, 60.3656, 97.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892106", "mag": 1.19, "time": 1505376712450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.799833, 38.712667, 4.08 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762815", "mag": 1.04, "time": 1505374690080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.221833, 32.924167, 12.12 ] } }, +{ "type": "Feature", "properties": { "id": "ak16824572", "mag": 1.6, "time": 1505374660381, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -144.7598, 65.436, 12.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000am75", "mag": 4.4, "time": 1505372640680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -72.6754, -34.2973, 1.87 ] } }, +{ "type": "Feature", "properties": { "id": "ak16824419", "mag": 1.8, "time": 1505372310107, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.5103, 60.0002, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762807", "mag": 1.14, "time": 1505372248820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.872333, 36.502833, 6.38 ] } }, +{ "type": "Feature", "properties": { "id": "ak16824418", "mag": 1.0, "time": 1505372093089, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8634, 59.8384, 41.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16824415", "mag": 1.3, "time": 1505371860862, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4454, 63.0596, 8.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762783", "mag": 1.64, "time": 1505371108250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.625167, 32.844, 11.98 ] } }, +{ "type": "Feature", "properties": { "id": "ak16824411", "mag": 1.3, "time": 1505371053195, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.1765, 60.359, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aywv", "mag": 4.0, "time": 1505370268660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.6903, 15.5507, 43.43 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762759", "mag": 1.32, "time": 1505370002700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.733, 33.668167, 13.69 ] } }, +{ "type": "Feature", "properties": { "id": "hv61907731", "mag": 1.75, "time": 1505369997330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.382, 19.236, 32.221 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762751", "mag": 0.96, "time": 1505369947950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.731167, 33.674333, 14.82 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aywt", "mag": 4.0, "time": 1505369661520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2582, 14.9559, 25.35 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892081", "mag": 1.08, "time": 1505369496760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.1615, 36.5675, 3.55 ] } }, +{ "type": "Feature", "properties": { "id": "us2000am6i", "mag": 4.5, "time": 1505369450740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.3229, 15.1323, 35.74 ] } }, +{ "type": "Feature", "properties": { "id": "us2000am6b", "mag": 4.4, "time": 1505369156780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7112, 15.4856, 25.87 ] } }, +{ "type": "Feature", "properties": { "id": "us2000am61", "mag": 3.0, "time": 1505368177800, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.3656, 36.7402, 7.992 ] } }, +{ "type": "Feature", "properties": { "id": "hv61907641", "mag": 2.26, "time": 1505367585250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.425667, 19.294167, 8.845 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arcx", "mag": 3.2, "time": 1505367393080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4046, 51.5999, 12.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000am5i", "mag": 4.2, "time": 1505366427980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.0841, 14.4266, 49.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amaf", "mag": 4.7, "time": 1505366112080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 148.0489, -1.356, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892391", "mag": 1.0, "time": 1505365754150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.669167, 40.386833, 6.29 ] } }, +{ "type": "Feature", "properties": { "id": "us2000am56", "mag": 4.7, "time": 1505365399680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.0709, 14.4637, 52.71 ] } }, +{ "type": "Feature", "properties": { "id": "mb80255284", "mag": 0.98, "time": 1505365218550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.522, 46.8975, 13.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16861140", "mag": 1.2, "time": 1505365047321, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0097, 62.5721, 78.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762615", "mag": 0.95, "time": 1505364900090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.405833, 33.049333, 3.39 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892056", "mag": 1.38, "time": 1505364695740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.834, 37.54, 4.68 ] } }, +{ "type": "Feature", "properties": { "id": "uw61307352", "mag": 1.78, "time": 1505364485340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.942833, 46.866667, 10.19 ] } }, +{ "type": "Feature", "properties": { "id": "ak16824230", "mag": 1.9, "time": 1505364358950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.959, 59.8075, 60.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762599", "mag": 1.23, "time": 1505364106870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.992833, 33.957167, 16.75 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762591", "mag": 2.12, "time": 1505363550640, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.864667, 34.336333, 2.71 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892041", "mag": 1.83, "time": 1505363410540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.834167, 37.540667, 4.76 ] } }, +{ "type": "Feature", "properties": { "id": "ak16824097", "mag": 1.0, "time": 1505363016608, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.1668, 62.6309, 61.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000am4b", "mag": 3.2, "time": 1505362481060, "felt": 8, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.9406, 37.3096, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823967", "mag": 2.0, "time": 1505361191283, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2972, 61.0176, 70.0 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017257000", "mag": 4.32, "time": 1505360450920, "felt": 14, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -68.791, 18.2223, 133.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000am3s", "mag": 3.3, "time": 1505360430180, "felt": 7, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.5112, 36.2854, 3.99 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762583", "mag": 1.43, "time": 1505358534420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.6335, 37.005167, 1.55 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762575", "mag": 1.39, "time": 1505358219310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.606667, 32.828, 12.41 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762567", "mag": 1.41, "time": 1505358109150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.427667, 34.225833, 13.02 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amd4", "mag": 3.2, "time": 1505357901130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4442, 42.5241, 6.99 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amd0", "mag": 3.1, "time": 1505357873450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4212, 42.5232, 8.42 ] } }, +{ "type": "Feature", "properties": { "id": "us2000am2z", "mag": 4.0, "time": 1505357591000, "felt": 5, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4618, 42.5096, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "uu60245162", "mag": 3.43, "time": 1505357581000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.426833, 42.522333, 7.86 ] } }, +{ "type": "Feature", "properties": { "id": "ak16861134", "mag": 1.6, "time": 1505356675370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.8887, 59.6609, 90.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823826", "mag": 1.2, "time": 1505356643722, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.394, 60.1683, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000am28", "mag": 2.4, "time": 1505356555350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4263, 42.5303, 6.85 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605135", "mag": 1.0, "time": 1505356439739, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.8899, 37.3603, 8.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823823", "mag": 1.2, "time": 1505356197786, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.8776, 62.7371, 2.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892031", "mag": 0.98, "time": 1505355727940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.737663, 38.785168, 2.12 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892026", "mag": 1.09, "time": 1505355720450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.746833, 38.787833, 0.11 ] } }, +{ "type": "Feature", "properties": { "id": "ak16861131", "mag": 1.7, "time": 1505355503652, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2915, 59.077, 76.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72892021", "mag": 1.67, "time": 1505355378570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.139667, 37.139, 11.31 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823809", "mag": 1.2, "time": 1505354254705, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.3285, 60.1933, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000am21", "mag": 3.2, "time": 1505353999720, "felt": 13, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 22.899, 42.6704, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762543", "mag": 1.21, "time": 1505353838790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.543667, 34.513833, 6.53 ] } }, +{ "type": "Feature", "properties": { "id": "us2000am1y", "mag": 2.6, "time": 1505353481360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4312, 42.6014, 6.92 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823693", "mag": 1.0, "time": 1505351348552, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.644, 62.6994, 58.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823694", "mag": 2.1, "time": 1505351146642, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -160.5002, 54.7664, 27.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823688", "mag": 1.1, "time": 1505350854568, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.6619, 59.8124, 15.7 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017257001", "mag": 1.33, "time": 1505350270080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.141, 18.0321, 11.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823577", "mag": 2.7, "time": 1505349755149, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -161.3635, 54.4582, 4.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16861124", "mag": 1.1, "time": 1505349382106, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.2989, 65.668, 14.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000am0x", "mag": 4.6, "time": 1505348843700, "felt": 139, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 139.6152, 35.7719, 48.83 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762495", "mag": 1.0, "time": 1505347877510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.3345, 33.3545, 11.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823574", "mag": 2.8, "time": 1505347636545, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.3466, 52.1109, 79.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823573", "mag": 2.3, "time": 1505347560653, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4123, 51.617, 13.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762487", "mag": 1.28, "time": 1505347417680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.2715, 33.976667, 5.05 ] } }, +{ "type": "Feature", "properties": { "id": "hv61907326", "mag": 1.75, "time": 1505347375860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.394165, 19.238333, 32.54 ] } }, +{ "type": "Feature", "properties": { "id": "ak16861121", "mag": 1.7, "time": 1505347241023, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4, 51.6505, 10.1 ] } }, +{ "type": "Feature", "properties": { "id": "hv61907236", "mag": 2.19, "time": 1505347011230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.3835, 19.243, 32.131 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891986", "mag": 1.15, "time": 1505346581750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.5475, 37.143167, 3.07 ] } }, +{ "type": "Feature", "properties": { "id": "uw61307262", "mag": 1.18, "time": 1505346312450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.458833, 45.814167, -0.95 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823443", "mag": 1.7, "time": 1505346090013, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3313, 60.824, 55.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762463", "mag": 2.21, "time": 1505345845770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.610333, 32.834, 14.54 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762455", "mag": 1.23, "time": 1505345794660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.613333, 32.828, 12.93 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823442", "mag": 1.4, "time": 1505345681125, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.1366, 63.4085, 115.9 ] } }, +{ "type": "Feature", "properties": { "id": "mb80255184", "mag": 0.99, "time": 1505345517200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.161833, 48.091333, 6.16 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823441", "mag": 1.4, "time": 1505345131416, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9358, 61.9565, 65.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000alzg", "mag": 4.2, "time": 1505344897150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -69.4183, -18.058, 145.27 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823332", "mag": 2.8, "time": 1505344031893, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.3482, 51.3154, 44.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823330", "mag": 1.3, "time": 1505343882913, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3403, 64.9963, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000alyy", "mag": 3.2, "time": 1505343206750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5646, 46.8793, 10.55 ] } }, +{ "type": "Feature", "properties": { "id": "uw61307247", "mag": 1.57, "time": 1505343065140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.347833, 44.090833, -1.55 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762423", "mag": 2.63, "time": 1505342925380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.6105, 32.832833, 13.39 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70235168", "mag": 1.72, "time": 1505342816860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.966333, 37.277833, 4.1 ] } }, +{ "type": "Feature", "properties": { "id": "uu60245097", "mag": 1.4, "time": 1505342728590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.0425, 44.6825, 13.02 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762407", "mag": 1.11, "time": 1505342669930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.2705, 33.978, 5.78 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830577", "mag": 2.2, "time": 1505342546550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -159.6253, 55.5692, 53.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762415", "mag": 1.75, "time": 1505342494590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.999333, 33.073, -0.12 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605103", "mag": 1.1, "time": 1505342257553, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.367, 38.5022, 1.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762399", "mag": 1.66, "time": 1505342009270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.612333, 32.834667, 12.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762391", "mag": 1.75, "time": 1505341937760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.613, 32.838667, 12.07 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762383", "mag": 1.83, "time": 1505341540510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.614, 32.8335, 12.31 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762367", "mag": 3.47, "time": 1505341287040, "felt": 39, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.615833, 32.843833, 15.23 ] } }, +{ "type": "Feature", "properties": { "id": "hv61907176", "mag": 1.67, "time": 1505340803980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.213667, 19.3035, 2.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823316", "mag": 2.5, "time": 1505340733287, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.3859, 61.6698, 29.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891951", "mag": 1.45, "time": 1505340188960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.841667, 37.532167, -1.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830575", "mag": 1.5, "time": 1505340177499, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.5229, 57.7401, 52.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762359", "mag": 1.73, "time": 1505340060360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.274, 33.976333, 5.08 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762351", "mag": 3.26, "time": 1505339982500, "felt": 19, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.276, 33.975333, 3.91 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830574", "mag": 1.6, "time": 1505339727053, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -167.4531, 53.5386, 11.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823310", "mag": 1.1, "time": 1505339360762, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.5682, 53.9212, 8.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762343", "mag": 1.12, "time": 1505339170890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.795167, 33.507167, 4.82 ] } }, +{ "type": "Feature", "properties": { "id": "mb80255169", "mag": 1.13, "time": 1505339091750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.622667, 46.909667, 10.61 ] } }, +{ "type": "Feature", "properties": { "id": "us2000alwi", "mag": 4.7, "time": 1505338937260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0086, 15.1566, 38.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762335", "mag": 1.17, "time": 1505338520010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.614667, 32.832167, 10.18 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762327", "mag": 1.59, "time": 1505338477140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.615333, 32.843, 15.01 ] } }, +{ "type": "Feature", "properties": { "id": "uu60245082", "mag": 1.54, "time": 1505338298430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.043833, 44.678167, 13.53 ] } }, +{ "type": "Feature", "properties": { "id": "us2000alvq", "mag": 5.0, "time": 1505338251370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9904, 15.7092, 39.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891936", "mag": 1.29, "time": 1505338239110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.017333, 37.5655, -0.37 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762303", "mag": 1.69, "time": 1505337757160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.7965, 33.504167, 5.32 ] } }, +{ "type": "Feature", "properties": { "id": "uu60245072", "mag": 1.82, "time": 1505336663200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.075667, 44.674, 5.83 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762287", "mag": 1.49, "time": 1505336435640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.498833, 33.8575, -0.61 ] } }, +{ "type": "Feature", "properties": { "id": "mb80255154", "mag": 2.29, "time": 1505335433020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.7145, 46.9035, 15.16 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891916", "mag": 1.11, "time": 1505334220120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7985, 38.833168, 1.37 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891911", "mag": 1.01, "time": 1505333988430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.811165, 38.815666, 2.78 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823196", "mag": 1.7, "time": 1505333862556, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2791, 60.1339, 58.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891901", "mag": 1.64, "time": 1505333181410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.814, 38.8085, 2.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891896", "mag": 1.52, "time": 1505332739060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.817667, 37.481167, 0.23 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762231", "mag": 1.56, "time": 1505331922920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.381833, 35.980833, 4.99 ] } }, +{ "type": "Feature", "properties": { "id": "us2000alqh", "mag": 4.6, "time": 1505331447000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 112.9501, -6.0986, 590.53 ] } }, +{ "type": "Feature", "properties": { "id": "us2000alq6", "mag": 3.0, "time": 1505331233180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4525, 42.6029, 6.02 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823083", "mag": 1.8, "time": 1505330838320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.8987, 61.0912, 0.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823082", "mag": 1.3, "time": 1505330810883, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.7682, 61.1384, 6.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823080", "mag": 1.9, "time": 1505329947650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.7636, 59.6753, 80.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762215", "mag": 1.01, "time": 1505329786970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.1445, 33.667, -0.63 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891881", "mag": 1.2, "time": 1505329775160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.850167, 37.644667, 5.63 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762207", "mag": 1.15, "time": 1505329688010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.187167, 34.993167, -0.82 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830566", "mag": 2.0, "time": 1505328672149, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.302, 51.3949, 36.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822979", "mag": 1.3, "time": 1505328502909, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.3078, 61.2967, 15.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891876", "mag": 1.1, "time": 1505327236230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.745666, 38.787834, 1.52 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822977", "mag": 1.3, "time": 1505326599778, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0157, 63.5538, 1.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891871", "mag": 2.5, "time": 1505325897250, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.0595, 40.449667, 16.29 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891866", "mag": 1.77, "time": 1505325532440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.0005, 35.943167, 17.23 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891861", "mag": 1.4, "time": 1505325215290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.600167, 35.482, -0.46 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762175", "mag": 1.47, "time": 1505324991750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.609, 32.840667, 14.81 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822975", "mag": 1.2, "time": 1505324283732, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.2438, 62.4485, 2.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891851", "mag": 1.07, "time": 1505324016940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.841167, 37.491667, -0.1 ] } }, +{ "type": "Feature", "properties": { "id": "se60179327", "mag": 3.2, "time": 1505323990930, "felt": 525, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -80.703, 37.472833, 17.77 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822973", "mag": 1.1, "time": 1505323870033, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.7446, 59.8908, 41.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830561", "mag": 1.8, "time": 1505323399318, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.9553, 59.6095, 109.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830560", "mag": 2.0, "time": 1505322404855, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.5059, 60.1768, 153.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000alkc", "mag": 4.4, "time": 1505321962400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.6803, 15.7969, 43.13 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830559", "mag": 1.8, "time": 1505321554841, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.8197, 51.97, 7.3 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891831", "mag": 2.56, "time": 1505318816290, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -124.704667, 40.484, 16.91 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822799", "mag": 1.8, "time": 1505318719906, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.4098, 51.7491, 29.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822798", "mag": 1.1, "time": 1505318596103, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.8143, 62.8428, 67.1 ] } }, +{ "type": "Feature", "properties": { "id": "hv61906796", "mag": 2.1, "time": 1505317840280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.485504, 19.219, 36.43 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822695", "mag": 1.3, "time": 1505316869586, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4592, 63.3484, 0.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asbr", "mag": 4.3, "time": 1505316791790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 152.1284, -4.88, 54.06 ] } }, +{ "type": "Feature", "properties": { "id": "hv61906781", "mag": 1.87, "time": 1505316745210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.889333, 19.9115, 24.592 ] } }, +{ "type": "Feature", "properties": { "id": "us2000alhx", "mag": 5.0, "time": 1505316098600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 161.9266, -10.7647, 46.64 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822692", "mag": 2.1, "time": 1505315572825, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.2966, 59.7717, 67.1 ] } }, +{ "type": "Feature", "properties": { "id": "nm60179312", "mag": 1.77, "time": 1505315298800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -89.672667, 36.156667, 9.37 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822691", "mag": 1.8, "time": 1505315111913, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.8055, 59.8229, 63.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822689", "mag": 1.5, "time": 1505313796189, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.627, 60.7945, 30.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762039", "mag": 1.34, "time": 1505312641900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.791, 36.012167, 1.22 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605012", "mag": 1.1, "time": 1505309502885, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9116, 38.3879, 15.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830551", "mag": 1.1, "time": 1505309158928, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.8896, 60.3719, 15.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822590", "mag": 1.1, "time": 1505309077336, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.3908, 66.2048, 11.9 ] } }, +{ "type": "Feature", "properties": { "id": "mb80255099", "mag": 1.92, "time": 1505309076210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.547833, 44.257, 9.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891776", "mag": 1.02, "time": 1505308975510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.918167, 37.593167, 0.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822588", "mag": 1.4, "time": 1505308950441, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.4711, 65.4989, 11.1 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604990", "mag": 2.3, "time": 1505308914949, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.818, 38.8311, 8.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci37762007", "mag": 2.3, "time": 1505308483530, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.585667, 35.139667, 1.62 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761999", "mag": 1.26, "time": 1505308208470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.6185, 32.838, 13.81 ] } }, +{ "type": "Feature", "properties": { "id": "hv61906676", "mag": 1.95, "time": 1505307948740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.298996, 19.424334, 6.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761983", "mag": 1.11, "time": 1505307567020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.623, 32.839333, 10.27 ] } }, +{ "type": "Feature", "properties": { "id": "us2000alfh", "mag": 4.5, "time": 1505306912090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.7023, 15.8472, 95.22 ] } }, +{ "type": "Feature", "properties": { "id": "mb80255094", "mag": 1.19, "time": 1505305625190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.642667, 46.956667, 13.27 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761967", "mag": 0.99, "time": 1505305387220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.587333, 36.179667, 0.99 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891766", "mag": 1.15, "time": 1505305306770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.820333, 38.804, 2.93 ] } }, +{ "type": "Feature", "properties": { "id": "us2000anw3", "mag": 2.5, "time": 1505305272030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -163.6774, 53.9359, 13.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761959", "mag": 1.4, "time": 1505304763660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.829167, 32.782333, 3.76 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asbk", "mag": 4.1, "time": 1505303510580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 128.1783, 2.9917, 58.22 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891751", "mag": 0.99, "time": 1505303358450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.082167, 35.707667, 6.66 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822583", "mag": 1.1, "time": 1505302645910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.3182, 60.2384, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822582", "mag": 2.3, "time": 1505302558389, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.6566, 51.5758, 56.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000alew", "mag": 3.9, "time": 1505302030040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2516, 14.855, 22.24 ] } }, +{ "type": "Feature", "properties": { "id": "mb80255084", "mag": 1.07, "time": 1505300960250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.511667, 46.9035, 5.32 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822577", "mag": 1.5, "time": 1505300414194, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.9212, 64.7545, 3.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000alee", "mag": 3.3, "time": 1505299970430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.6225, 59.7836, 5.44 ] } }, +{ "type": "Feature", "properties": { "id": "uu60244877", "mag": 2.35, "time": 1505299838240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.8535, 44.770833, 7.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891746", "mag": 1.53, "time": 1505299590270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.793, 38.8215, 3.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830540", "mag": 1.9, "time": 1505298481141, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.1134, 57.8805, 76.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000anw1", "mag": 3.0, "time": 1505298226550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 179.0008, 50.1653, 25.9 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604987", "mag": 1.7, "time": 1505298050456, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.8103, 39.3643, 9.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822473", "mag": 1.2, "time": 1505297484913, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4897, 63.0467, 3.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822472", "mag": 2.4, "time": 1505297294726, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.0416, 53.5692, 24.5 ] } }, +{ "type": "Feature", "properties": { "id": "uw61307017", "mag": 1.34, "time": 1505297037790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.764333, 48.271333, 1.82 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830536", "mag": 1.2, "time": 1505297029108, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.7778, 60.5002, 3.8 ] } }, +{ "type": "Feature", "properties": { "id": "uu60244867", "mag": 2.44, "time": 1505296698750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.422, 42.567833, 7.73 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aldk", "mag": 4.3, "time": 1505296627560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9055, 15.639, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761935", "mag": 1.02, "time": 1505296379600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.6215, 32.831333, 10.19 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aldd", "mag": 4.5, "time": 1505295980580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7401, 15.5449, 31.41 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ald3", "mag": 2.4, "time": 1505295918600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.9039, 36.2089, 4.448 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822468", "mag": 2.5, "time": 1505295654705, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -158.2898, 58.6446, 4.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ald0", "mag": 4.3, "time": 1505295123840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 179.5523, -23.5684, 541.35 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822374", "mag": 2.1, "time": 1505294583800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.5476, 52.7346, 39.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000alcs", "mag": 3.9, "time": 1505294302600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2348, 15.2732, 42.03 ] } }, +{ "type": "Feature", "properties": { "id": "hv61906586", "mag": 2.11, "time": 1505294188360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.356003, 19.467167, 4.72 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891726", "mag": 1.09, "time": 1505293695870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.793831, 38.822334, 2.17 ] } }, +{ "type": "Feature", "properties": { "id": "us2000alcf", "mag": 2.6, "time": 1505292526080, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4275, 42.596, 6.01 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822373", "mag": 1.5, "time": 1505292217097, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.4702, 60.5679, 7.7 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604985", "mag": 1.6, "time": 1505292088777, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.548, 37.4198, 12.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891721", "mag": 1.57, "time": 1505290933360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.889333, 39.366167, 10.36 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822371", "mag": 1.4, "time": 1505290808147, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.8609, 62.2453, 3.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822294", "mag": 1.5, "time": 1505289269698, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7566, 62.9227, 94.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822278", "mag": 1.1, "time": 1505287972451, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.7433, 64.7476, 3.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822251", "mag": 3.4, "time": 1505287366858, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.5871, 61.6459, 24.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822240", "mag": 4.2, "time": 1505287337046, "felt": 42, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.9213, 62.8983, 79.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000albc", "mag": 2.3, "time": 1505286819380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4494, 42.6632, 10.21 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830527", "mag": 1.8, "time": 1505286603893, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0388, 59.8755, 109.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822236", "mag": 1.3, "time": 1505286374065, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.3111, 60.5579, 12.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891681", "mag": 1.39, "time": 1505286150510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8285, 37.467, -1.65 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822233", "mag": 1.6, "time": 1505285865490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.8651, 62.2629, 96.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000alb7", "mag": 2.6, "time": 1505285839040, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4177, 42.5618, 8.28 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830523", "mag": 1.7, "time": 1505285675768, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.1432, 53.7072, 69.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000alb2", "mag": 4.5, "time": 1505284765560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -179.084, -22.1327, 549.09 ] } }, +{ "type": "Feature", "properties": { "id": "nn00605030", "mag": 1.1, "time": 1505284250632, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9094, 38.3681, 5.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830521", "mag": 1.2, "time": 1505284146176, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.8175, 60.5189, 13.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000alax", "mag": 4.7, "time": 1505283996200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 147.6079, 13.4506, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891656", "mag": 2.62, "time": 1505283657320, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.803833, 37.486167, 2.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761831", "mag": 1.06, "time": 1505283115050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.795667, 33.5045, 6.22 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822160", "mag": 1.4, "time": 1505282783934, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.9732, 60.9785, 5.5 ] } }, +{ "type": "Feature", "properties": { "id": "mb80255029", "mag": 1.01, "time": 1505281846410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5335, 46.862167, 10.42 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822085", "mag": 1.5, "time": 1505279524459, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -144.8464, 60.3009, 18.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ala9", "mag": 4.5, "time": 1505279374230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.453, 15.3914, 72.28 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761799", "mag": 0.97, "time": 1505279080610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.108167, 34.0375, 6.71 ] } }, +{ "type": "Feature", "properties": { "id": "ak16830517", "mag": 1.1, "time": 1505278511333, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.4202, 60.2062, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80255024", "mag": 0.95, "time": 1505278401320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.529833, 46.864167, 11.03 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891626", "mag": 1.1, "time": 1505277590570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.657667, 37.1885, 3.74 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891621", "mag": 1.74, "time": 1505277415750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.886167, 39.3655, 10.44 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822082", "mag": 1.6, "time": 1505275993590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.0455, 67.102, 9.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891611", "mag": 1.07, "time": 1505275610780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.795, 38.834667, 1.79 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822080", "mag": 3.5, "time": 1505275475357, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4947, 51.6652, 10.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891606", "mag": 2.64, "time": 1505275168490, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.793833, 38.835667, 1.89 ] } }, +{ "type": "Feature", "properties": { "id": "mb80255014", "mag": 0.96, "time": 1505274355010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.537, 46.87, 9.71 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891581", "mag": 0.95, "time": 1505273207520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.795166, 38.836666, 1.37 ] } }, +{ "type": "Feature", "properties": { "id": "mb80255009", "mag": 1.36, "time": 1505273099690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.536167, 46.872333, 11.58 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017256002", "mag": 2.65, "time": 1505272611930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -66.4988, 19.1065, 25.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891561", "mag": 0.95, "time": 1505272540610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.796669, 38.836834, 1.67 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891556", "mag": 1.43, "time": 1505272430980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.798333, 38.835167, 1.85 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891551", "mag": 2.57, "time": 1505272400990, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.795667, 38.835, 1.82 ] } }, +{ "type": "Feature", "properties": { "id": "us2000al90", "mag": 4.7, "time": 1505272023240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -73.0946, 9.5711, 124.17 ] } }, +{ "type": "Feature", "properties": { "id": "mb80255004", "mag": 1.06, "time": 1505270988240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.532, 46.864667, 11.36 ] } }, +{ "type": "Feature", "properties": { "id": "us2000al8v", "mag": 4.4, "time": 1505270586710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5721, 15.2889, 34.84 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761727", "mag": 1.4, "time": 1505270305170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.643667, 34.5065, 17.68 ] } }, +{ "type": "Feature", "properties": { "id": "ak16822007", "mag": 1.0, "time": 1505269102037, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6691, 63.5608, 10.3 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017256000", "mag": 3.12, "time": 1505269072880, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -66.5123, 19.091, 21.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891541", "mag": 1.06, "time": 1505268817240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.517833, 36.804167, 4.87 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821999", "mag": 1.7, "time": 1505268378179, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.2198, 61.7575, 9.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000al86", "mag": 5.0, "time": 1505268098300, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5276, 15.1558, 14.07 ] } }, +{ "type": "Feature", "properties": { "id": "mb80254989", "mag": 1.38, "time": 1505267929610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.540667, 46.872333, 11.48 ] } }, +{ "type": "Feature", "properties": { "id": "mb80254984", "mag": 0.99, "time": 1505267728460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5535, 46.8885, 10.76 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821934", "mag": 1.1, "time": 1505267091152, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2406, 64.8451, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891516", "mag": 1.94, "time": 1505266613010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.366833, 40.4805, 29.25 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017256001", "mag": 3.05, "time": 1505266581450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -66.5053, 19.0955, 25.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761639", "mag": 2.16, "time": 1505265949130, "felt": 80, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.768667, 33.774833, 2.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821933", "mag": 1.0, "time": 1505265920217, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.4031, 60.2216, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761631", "mag": 1.35, "time": 1505265794450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.333667, 32.933167, 11.47 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821931", "mag": 1.3, "time": 1505265469603, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.5511, 61.3707, 12.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000al7y", "mag": 4.1, "time": 1505265414270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4234, 15.3254, 35.74 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821926", "mag": 2.1, "time": 1505265047390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.5313, 60.6712, 14.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821924", "mag": 1.7, "time": 1505264772966, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -158.5006, 65.2775, 11.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000al7s", "mag": 4.1, "time": 1505263876510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -95.3188, 15.5954, 29.98 ] } }, +{ "type": "Feature", "properties": { "id": "hv61906111", "mag": 1.46, "time": 1505262900730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.538167, 19.256333, 8.429 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891421", "mag": 1.92, "time": 1505262602400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.273167, 36.148167, 8.47 ] } }, +{ "type": "Feature", "properties": { "id": "hv61906101", "mag": 2.02, "time": 1505262046800, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.276672, 19.404333, 0.19 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891406", "mag": 1.7, "time": 1505261981400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.865667, 36.439667, 6.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000al7a", "mag": 3.9, "time": 1505261942310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.399, 14.9659, 29.81 ] } }, +{ "type": "Feature", "properties": { "id": "hv61906081", "mag": 1.94, "time": 1505261244650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.535, 19.849, 23.752 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761535", "mag": 1.56, "time": 1505261179000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.165833, 34.0375, 5.82 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850793", "mag": 2.2, "time": 1505260675964, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.4757, 53.3828, 38.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821817", "mag": 1.0, "time": 1505258496556, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -144.5762, 67.0334, 2.1 ] } }, +{ "type": "Feature", "properties": { "id": "uw61306902", "mag": 1.1, "time": 1505258286020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.374667, 45.693833, -0.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000al6d", "mag": 4.9, "time": 1505257835180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -32.4621, 58.0975, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761503", "mag": 1.49, "time": 1505257449290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.675833, 35.043, -0.82 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821811", "mag": 1.3, "time": 1505256864247, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3463, 64.994, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "hv61905981", "mag": 1.81, "time": 1505256516770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.543333, 19.851167, 24.833 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821806", "mag": 2.7, "time": 1505256286618, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.4621, 65.79, 5.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821804", "mag": 1.5, "time": 1505255958164, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.3411, 61.6898, 7.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000al5m", "mag": 4.0, "time": 1505255324930, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -70.8843, -20.2485, 15.05 ] } }, +{ "type": "Feature", "properties": { "id": "us2000al5h", "mag": 4.8, "time": 1505254407650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -32.3543, 58.0241, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891326", "mag": 1.22, "time": 1505251854350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.794833, 38.819333, 2.91 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761407", "mag": 1.17, "time": 1505251524970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.193167, 34.9985, -0.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000al44", "mag": 4.6, "time": 1505250860230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -32.4259, 58.0753, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821734", "mag": 1.5, "time": 1505250673775, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.907, 60.3564, 8.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000al3g", "mag": 4.9, "time": 1505250247360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -32.4208, 58.165, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891306", "mag": 1.1, "time": 1505250244890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.819333, 37.604167, 3.81 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761383", "mag": 1.74, "time": 1505250166450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.805333, 33.691833, 15.39 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761375", "mag": 1.49, "time": 1505248746150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.3685, 33.956333, 12.98 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761367", "mag": 1.03, "time": 1505248730160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.575167, 33.465333, 9.81 ] } }, +{ "type": "Feature", "properties": { "id": "us2000al2x", "mag": 4.8, "time": 1505248700330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.19, -15.0799, 144.26 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891286", "mag": 2.07, "time": 1505247727770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.5795, 39.603833, -0.21 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821575", "mag": 1.5, "time": 1505247191039, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.9811, 64.7032, 15.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000al1n", "mag": 2.7, "time": 1505247025290, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.3683, 36.7446, 14.63 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891281", "mag": 1.59, "time": 1505246933110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.827333, 38.839, 2.11 ] } }, +{ "type": "Feature", "properties": { "id": "us2000al1t", "mag": 4.3, "time": 1505246854930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4239, 15.7169, 52.92 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891276", "mag": 1.98, "time": 1505246713670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.876833, 37.8095, 14.44 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850781", "mag": 1.8, "time": 1505246486363, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.5902, 57.2026, 44.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761335", "mag": 0.96, "time": 1505246263650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.759333, 33.8575, 5.49 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761319", "mag": 2.18, "time": 1505245563030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.385, 32.3285, 10.39 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850780", "mag": 3.0, "time": 1505245054736, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -170.5817, 52.3665, 32.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821568", "mag": 1.3, "time": 1505244764083, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.4179, 63.5705, 4.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891271", "mag": 2.16, "time": 1505244492580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.146667, 40.211833, 2.94 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891266", "mag": 1.1, "time": 1505244145950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.875667, 38.839667, 2.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000al0z", "mag": 4.4, "time": 1505243754080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.7715, -21.9227, 347.97 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821516", "mag": 1.4, "time": 1505243650979, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.5267, 60.0018, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821564", "mag": 1.6, "time": 1505243467122, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -159.2171, 59.7927, 8.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akzt", "mag": 4.7, "time": 1505243351270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -32.2455, 58.0337, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akzf", "mag": 4.3, "time": 1505243172030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.6417, 15.6677, 51.24 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akyq", "mag": 4.4, "time": 1505241724530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9743, 16.3622, 66.45 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891231", "mag": 1.19, "time": 1505241397800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.244667, 39.3805, 3.22 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akyh", "mag": 4.4, "time": 1505241368140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.5996, 15.3334, 74.72 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aky8", "mag": 4.6, "time": 1505240973270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0643, 15.2212, 44.65 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850775", "mag": 1.7, "time": 1505240703529, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2159, 59.366, 81.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akxq", "mag": 2.8, "time": 1505240585080, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4572, 42.5165, 8.78 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821457", "mag": 1.1, "time": 1505238948365, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.1631, 60.0754, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850772", "mag": 1.0, "time": 1505238898070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.2683, 61.5446, 35.4 ] } }, +{ "type": "Feature", "properties": { "id": "hv61905641", "mag": 2.1, "time": 1505238187460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.247667, 19.393167, 36.582 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aq68", "mag": 2.8, "time": 1505237765880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -158.9785, 55.7766, 56.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akwr", "mag": 4.3, "time": 1505237620800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 129.6779, -5.2108, 218.06 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821449", "mag": 2.3, "time": 1505236529463, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -167.4402, 53.5209, 13.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821379", "mag": 2.4, "time": 1505235536293, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.4636, 60.5717, 9.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akvp", "mag": 4.5, "time": 1505235493410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.2449, 15.2798, 73.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aq63", "mag": 3.1, "time": 1505235473870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -167.5043, 53.6304, 25.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821334", "mag": 1.0, "time": 1505235138364, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -142.7095, 60.5946, 14.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891191", "mag": 1.63, "time": 1505235102110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.444167, 37.384167, 12.11 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akwm", "mag": 4.6, "time": 1505234310180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -58.4081, 13.9047, 20.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821326", "mag": 1.9, "time": 1505234239386, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.7021, 63.9919, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761199", "mag": 1.12, "time": 1505233979950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.139333, 35.857167, 3.42 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821324", "mag": 1.0, "time": 1505233378354, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.8118, 65.9855, 3.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821323", "mag": 2.3, "time": 1505232589454, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -176.3915, 52.0051, 11.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891166", "mag": 1.17, "time": 1505232534860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.976167, 37.596833, 8.18 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akua", "mag": 4.5, "time": 1505231911880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 129.3156, -7.5665, 115.97 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761183", "mag": 1.38, "time": 1505231682740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.031667, 33.866, 11.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891131", "mag": 1.13, "time": 1505231490780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.821167, 37.605, 4.21 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aq60", "mag": 3.4, "time": 1505230949090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -171.7818, 52.0274, 61.84 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akty", "mag": 4.1, "time": 1505230831380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.0909, 55.1751, 22.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asax", "mag": 4.2, "time": 1505230532990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -179.919, -24.5557, 553.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aktu", "mag": 5.0, "time": 1505230101200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.9204, 15.0356, 34.73 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761159", "mag": 0.99, "time": 1505229927560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.794, 33.505667, 4.44 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akts", "mag": 4.4, "time": 1505229916500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4589, 15.8693, 40.82 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850759", "mag": 2.0, "time": 1505229684203, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.4729, 57.3614, 66.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asau", "mag": 4.5, "time": 1505228968140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.2892, -30.4261, 12.38 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akt9", "mag": 4.7, "time": 1505227714260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 167.6472, -14.1046, 43.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821264", "mag": 1.4, "time": 1505227661290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.5591, 61.6356, 28.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821262", "mag": 1.8, "time": 1505227098718, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.5176, 60.4846, 107.4 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017255006", "mag": 3.11, "time": 1505226988680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.8866, 18.066, 112.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821260", "mag": 1.3, "time": 1505226855029, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.482, 62.559, 83.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761111", "mag": 1.33, "time": 1505226544460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.166, 34.036, 5.82 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891096", "mag": 1.34, "time": 1505226449930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7255, 38.788667, 1.77 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850755", "mag": 1.5, "time": 1505226255965, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.5898, 60.4951, 99.5 ] } }, +{ "type": "Feature", "properties": { "id": "uu60244417", "mag": 1.65, "time": 1505226014340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.334667, 44.621667, 2.11 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aq5x", "mag": 3.1, "time": 1505225597950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -171.3403, 52.1694, 67.96 ] } }, +{ "type": "Feature", "properties": { "id": "uu60244407", "mag": 1.34, "time": 1505225495130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.467, 42.663667, 3.54 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821259", "mag": 1.2, "time": 1505225438730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.3559, 60.1768, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821258", "mag": 1.2, "time": 1505225170339, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.1399, 60.3035, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821221", "mag": 1.0, "time": 1505223846302, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.7846, 53.7799, 6.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821217", "mag": 1.4, "time": 1505223357390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.7209, 60.3452, 65.8 ] } }, +{ "type": "Feature", "properties": { "id": "hv61905526", "mag": 1.72, "time": 1505223290340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.929167, 19.870667, 12.697 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821215", "mag": 1.4, "time": 1505223177976, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.314, 60.1844, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "uu60244352", "mag": 2.41, "time": 1505222826990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.443167, 42.595, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821210", "mag": 1.0, "time": 1505222200792, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.0089, 61.3182, 28.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akri", "mag": 2.9, "time": 1505221931200, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.9201, 36.2062, 6.163 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821207", "mag": 2.0, "time": 1505221802809, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9996, 62.229, 72.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akrz", "mag": 2.5, "time": 1505220235620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5432, 46.8852, 12.06 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821169", "mag": 1.1, "time": 1505219786301, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.9544, 67.3188, 9.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821166", "mag": 1.0, "time": 1505219272070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.0159, 59.8987, 11.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891076", "mag": 1.16, "time": 1505219059140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.820667, 37.602667, 4.12 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761079", "mag": 1.06, "time": 1505218941580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.819667, 33.71, 15.77 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850742", "mag": 2.4, "time": 1505218654701, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4252, 51.6857, 14.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821165", "mag": 1.0, "time": 1505218329490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.4876, 60.0043, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821163", "mag": 1.3, "time": 1505217760897, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4102, 62.0418, 78.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891061", "mag": 0.96, "time": 1505217348960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.826333, 37.602833, 3.87 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821126", "mag": 1.3, "time": 1505216937519, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.1452, 62.8895, 56.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821125", "mag": 1.1, "time": 1505216743699, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.6326, 60.2201, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821120", "mag": 1.7, "time": 1505216018269, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.0049, 60.6518, 14.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821119", "mag": 1.5, "time": 1505215652902, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.8093, 53.7706, 8.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akpn", "mag": 4.7, "time": 1505215606400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 101.7514, 27.9618, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850734", "mag": 1.1, "time": 1505215354092, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.0512, 61.2674, 7.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akpc", "mag": 4.2, "time": 1505214378050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.8032, 16.1985, 37.2 ] } }, +{ "type": "Feature", "properties": { "id": "uu60244277", "mag": 1.7, "time": 1505214238510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.430167, 38.334333, 2.58 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821114", "mag": 1.9, "time": 1505213809149, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.8883, 61.2794, 95.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891031", "mag": 1.31, "time": 1505213535320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.861167, 37.426667, 3.97 ] } }, +{ "type": "Feature", "properties": { "id": "uu60244252", "mag": 1.02, "time": 1505213356870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.007333, 44.7855, 7.95 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821079", "mag": 1.4, "time": 1505212565937, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.7135, 59.8217, 2.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72891026", "mag": 1.86, "time": 1505212446760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.801833, 35.832333, 9.72 ] } }, +{ "type": "Feature", "properties": { "id": "uw61306757", "mag": 1.64, "time": 1505211458410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.728833, 46.841667, -2.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821074", "mag": 1.9, "time": 1505210888686, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7981, 61.0848, 49.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci37761007", "mag": 0.97, "time": 1505210308130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.34, 33.3915, 3.45 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821073", "mag": 1.0, "time": 1505210226661, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.8733, 61.5592, 31.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aknn", "mag": 4.7, "time": 1505209925680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -173.31, -20.0675, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850728", "mag": 1.6, "time": 1505209600286, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.4588, 61.074, 107.6 ] } }, +{ "type": "Feature", "properties": { "id": "uu60244207", "mag": 2.1, "time": 1505209143550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.465333, 42.608333, 2.53 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850727", "mag": 1.6, "time": 1505208401509, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2489, 60.3172, 132.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821071", "mag": 1.7, "time": 1505208310612, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.6819, 58.4203, 78.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aknb", "mag": 4.4, "time": 1505208006490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7329, 15.7927, 47.14 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821038", "mag": 1.4, "time": 1505207062279, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.7269, 62.2754, 47.5 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017255004", "mag": 3.01, "time": 1505207032870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.6503, 18.1753, 12.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821031", "mag": 2.4, "time": 1505206694908, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.4161, 60.188, 103.5 ] } }, +{ "type": "Feature", "properties": { "id": "hv61905311", "mag": 2.02, "time": 1505206056030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.975333, 19.557, 44.801 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821027", "mag": 2.1, "time": 1505205093842, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.4164, 57.0134, 65.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aq5l", "mag": 3.0, "time": 1505204765080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.2778, 52.1101, 228.97 ] } }, +{ "type": "Feature", "properties": { "id": "nm60179282", "mag": 1.12, "time": 1505204172200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -89.554167, 36.472, 8.99 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asam", "mag": 4.1, "time": 1505203793240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 147.4651, -4.9334, 167.53 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821023", "mag": 1.4, "time": 1505203680731, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.1732, 61.3766, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aq5k", "mag": 2.8, "time": 1505203540370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -159.5128, 54.8119, 22.77 ] } }, +{ "type": "Feature", "properties": { "id": "ci37760911", "mag": 1.29, "time": 1505202683830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.019667, 34.347833, 1.32 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821022", "mag": 1.1, "time": 1505201992117, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.4302, 65.4772, 14.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aq5j", "mag": 3.4, "time": 1505201513110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -169.335, 52.1151, 36.52 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604832", "mag": 1.5, "time": 1505201175706, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.919, 38.3871, 7.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821017", "mag": 1.4, "time": 1505201121331, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.8746, 64.7668, 2.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akm6", "mag": 4.0, "time": 1505200774070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.6261, 15.7276, 39.07 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821016", "mag": 1.1, "time": 1505200723657, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.6326, 59.9341, 17.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890911", "mag": 1.14, "time": 1505200493800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.835833, 37.502, -0.69 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017255005", "mag": 3.62, "time": 1505200390090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -68.7348, 17.4213, 58.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000asal", "mag": 4.5, "time": 1505200235050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 175.9237, -40.6778, 35.49 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821015", "mag": 1.0, "time": 1505200050481, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.0733, 62.8571, 78.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890906", "mag": 1.85, "time": 1505199341840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.959667, 36.079833, 11.15 ] } }, +{ "type": "Feature", "properties": { "id": "ak16820976", "mag": 4.5, "time": 1505198623340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.0626, 55.2018, 8.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16820951", "mag": 1.3, "time": 1505198176732, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.6431, 63.3655, 4.3 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604828", "mag": 1.4, "time": 1505197517767, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.0826, 39.1124, 11.2 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604827", "mag": 2.8, "time": 1505197059215, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.294, 37.806, 4.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akla", "mag": 4.9, "time": 1505196044760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 70.8701, -26.0946, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37760839", "mag": 1.35, "time": 1505195823730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.070833, 34.124, 7.32 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850710", "mag": 1.4, "time": 1505195695881, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.9514, 59.3304, 53.9 ] } }, +{ "type": "Feature", "properties": { "id": "uu60244052", "mag": 1.22, "time": 1505195536580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.435667, 42.555167, 6.85 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akkz", "mag": 4.4, "time": 1505195184110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.3657, 15.4552, 61.44 ] } }, +{ "type": "Feature", "properties": { "id": "ak16820948", "mag": 1.9, "time": 1505194916797, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.7632, 53.2354, 44.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850708", "mag": 1.2, "time": 1505194707074, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5938, 63.2379, 122.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80254859", "mag": 1.15, "time": 1505194171440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.527333, 46.863, 11.45 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890836", "mag": 1.09, "time": 1505193911680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.735833, 38.760833, 1.36 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akkp", "mag": 4.6, "time": 1505193612080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.8716, 15.0886, 57.71 ] } }, +{ "type": "Feature", "properties": { "id": "ak16820908", "mag": 2.5, "time": 1505193453186, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.7231, 53.1426, 25.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akkk", "mag": 5.3, "time": 1505192927120, "felt": 8, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.832, 15.182, 60.95 ] } }, +{ "type": "Feature", "properties": { "id": "mb80254849", "mag": 1.28, "time": 1505192738900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5175, 46.899833, 10.92 ] } }, +{ "type": "Feature", "properties": { "id": "mb80254844", "mag": 1.54, "time": 1505192475320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.973833, 43.2425, 2.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16820905", "mag": 1.1, "time": 1505191714754, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.4231, 60.1297, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890796", "mag": 1.14, "time": 1505190808830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.835, 37.502667, -0.15 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890791", "mag": 1.45, "time": 1505190617760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.788, 37.455, 7.56 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017255003", "mag": 1.94, "time": 1505190564980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.3923, 18.5168, 23.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850705", "mag": 1.4, "time": 1505190149086, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.3144, 60.1274, 78.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850704", "mag": 1.8, "time": 1505189303211, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -158.0362, 56.0678, 8.4 ] } }, +{ "type": "Feature", "properties": { "id": "uu60243967", "mag": 1.29, "time": 1505189093580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.059333, 40.568667, 7.12 ] } }, +{ "type": "Feature", "properties": { "id": "hv61905031", "mag": 2.8, "time": 1505189080390, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.320667, 21.633833, 8.469 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017255001", "mag": 2.63, "time": 1505188852110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.3921, 18.5325, 19.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80254839", "mag": 2.17, "time": 1505188197080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.530167, 46.8705, 12.49 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70235033", "mag": 2.06, "time": 1505188185670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.492167, 37.299667, 4.92 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890766", "mag": 2.21, "time": 1505187928020, "felt": 6, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.319833, 40.4865, 13.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci37760735", "mag": 1.81, "time": 1505187547790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.287333, 34.079667, 14.28 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850702", "mag": 1.3, "time": 1505187086661, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.8075, 61.2964, 89.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850701", "mag": 1.4, "time": 1505186992230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.2832, 60.1725, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80254834", "mag": 1.19, "time": 1505186273780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.528833, 46.863667, 13.34 ] } }, +{ "type": "Feature", "properties": { "id": "ci37760703", "mag": 1.89, "time": 1505185679940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.797333, 33.494667, 4.01 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017255002", "mag": 2.13, "time": 1505185260690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -68.0131, 19.0945, 24.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890706", "mag": 2.85, "time": 1505184989380, "felt": 7, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.821333, 37.6055, 4.17 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890701", "mag": 1.11, "time": 1505184817490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.821333, 37.468667, -0.39 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890691", "mag": 2.54, "time": 1505184593110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -124.502, 40.2965, 19.04 ] } }, +{ "type": "Feature", "properties": { "id": "ci37760663", "mag": 0.96, "time": 1505184048300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.1715, 34.0385, 5.42 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890681", "mag": 1.03, "time": 1505183875680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.820667, 37.4715, -1.63 ] } }, +{ "type": "Feature", "properties": { "id": "ak16820879", "mag": 1.6, "time": 1505183679937, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.3232, 62.0502, 60.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850697", "mag": 1.5, "time": 1505183127519, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0397, 60.1249, 106.2 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017255000", "mag": 3.99, "time": 1505182040830, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -68.7961, 18.688, 102.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akii", "mag": 2.5, "time": 1505181688510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.445, 42.5935, 6.67 ] } }, +{ "type": "Feature", "properties": { "id": "ak16850696", "mag": 1.4, "time": 1505181679899, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.6734, 59.8319, 93.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16820869", "mag": 1.9, "time": 1505181012974, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.001, 59.4008, 36.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16820867", "mag": 1.9, "time": 1505180308488, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.5196, 59.9375, 123.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16820865", "mag": 1.6, "time": 1505179834308, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.8744, 63.0936, 89.7 ] } }, +{ "type": "Feature", "properties": { "id": "uu60243827", "mag": 1.28, "time": 1505179319200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.414167, 42.53, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890631", "mag": 0.96, "time": 1505179150280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.816, 37.475, 1.48 ] } }, +{ "type": "Feature", "properties": { "id": "ci37760623", "mag": 1.18, "time": 1505178887000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.025, 36.311333, 2.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890616", "mag": 1.11, "time": 1505178809900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.820167, 37.474167, -0.42 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akhk", "mag": 5.1, "time": 1505178756750, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.097, 15.4421, 48.35 ] } }, +{ "type": "Feature", "properties": { "id": "ak16820847", "mag": 1.9, "time": 1505178590464, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.8044, 60.0035, 75.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890606", "mag": 2.1, "time": 1505178296120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.819667, 37.471, -0.04 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akhe", "mag": 4.8, "time": 1505178017830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2744, 15.0853, 44.38 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akhb", "mag": 2.4, "time": 1505177859710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4236, 42.5422, 5.98 ] } }, +{ "type": "Feature", "properties": { "id": "ci37760607", "mag": 1.78, "time": 1505177706210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.796167, 33.491167, 3.15 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akh7", "mag": 2.8, "time": 1505177557480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4213, 42.5825, 7.47 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890576", "mag": 2.34, "time": 1505177324250, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.82, 37.473, 0.51 ] } }, +{ "type": "Feature", "properties": { "id": "hv61904866", "mag": 1.99, "time": 1505176986190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.857, 19.358667, 41.774 ] } }, +{ "type": "Feature", "properties": { "id": "ak16820845", "mag": 1.3, "time": 1505176784517, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.3458, 60.155, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890561", "mag": 1.42, "time": 1505176270180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8195, 37.4765, -0.54 ] } }, +{ "type": "Feature", "properties": { "id": "ak16820836", "mag": 2.9, "time": 1505175684396, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.1737, 62.7988, 8.1 ] } }, +{ "type": "Feature", "properties": { "id": "uu60243772", "mag": 1.28, "time": 1505175463030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.450167, 42.593667, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akgt", "mag": 2.7, "time": 1505175275390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.45, 42.6006, 6.65 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akgp", "mag": 3.1, "time": 1505174426060, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4619, 42.5922, 9.11 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amy6", "mag": 3.4, "time": 1505174223950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -173.0579, 52.772, 207.41 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amy5", "mag": 3.3, "time": 1505173482210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 178.0407, 51.8595, 146.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16820045", "mag": 1.1, "time": 1505171834061, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.9121, 61.9185, 44.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akg3", "mag": 4.4, "time": 1505171543900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.3251, 15.4699, 53.34 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890511", "mag": 1.3, "time": 1505171391890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.012, 37.426833, 3.03 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akfs", "mag": 4.2, "time": 1505169617100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.6345, 15.6178, 38.83 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akfr", "mag": 2.8, "time": 1505169599030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4698, 42.6061, 6.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827363", "mag": 2.0, "time": 1505169544066, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4581, 51.6497, 9.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16819990", "mag": 1.0, "time": 1505169272029, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.1659, 59.9838, 14.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827361", "mag": 1.5, "time": 1505168696545, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2029, 59.1798, 77.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci37760423", "mag": 1.26, "time": 1505168688630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.3355, 32.933, 10.81 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akf8", "mag": 5.0, "time": 1505168453040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9567, 15.7603, 48.25 ] } }, +{ "type": "Feature", "properties": { "id": "ak16819215", "mag": 1.5, "time": 1505167702707, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4466, 62.4273, 81.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar1k", "mag": 4.4, "time": 1505167046570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 152.2966, -4.9444, 49.23 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890491", "mag": 1.11, "time": 1505166863970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.544833, 37.529, 12.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akeb", "mag": 5.1, "time": 1505166728910, "felt": null, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ -178.3593, 51.5235, 54.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16819167", "mag": 1.4, "time": 1505166664445, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.3213, 60.2363, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akdz", "mag": 4.3, "time": 1505166482960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.1669, 15.1965, 62.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akdq", "mag": 2.6, "time": 1505166481930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4105, 42.5306, 6.58 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827357", "mag": 2.3, "time": 1505165942611, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.8283, 55.1229, 12.0 ] } }, +{ "type": "Feature", "properties": { "id": "uw61306477", "mag": 1.21, "time": 1505165549480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.1755, 46.198833, 3.06 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890461", "mag": 2.23, "time": 1505164836450, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.939, 35.641167, 4.35 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ayll", "mag": 4.1, "time": 1505164739710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.6724, 15.4385, 31.22 ] } }, +{ "type": "Feature", "properties": { "id": "ci37760359", "mag": 2.29, "time": 1505164180230, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.940167, 35.427833, 21.14 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akcq", "mag": 5.5, "time": 1505164150350, "felt": 7, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0139, 14.9074, 27.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akch", "mag": 2.4, "time": 1505164053450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4202, 42.5566, 9.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827356", "mag": 1.9, "time": 1505163754769, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -173.4142, 51.8321, 32.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci37760351", "mag": 1.47, "time": 1505163661880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.9785, 32.6095, -0.36 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827355", "mag": 1.0, "time": 1505163537708, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -144.7591, 65.4356, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604742", "mag": 1.3, "time": 1505163193915, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9149, 38.3846, 5.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akbz", "mag": 4.1, "time": 1505162450200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -173.477, 52.2896, 65.69 ] } }, +{ "type": "Feature", "properties": { "id": "mb80254709", "mag": 1.54, "time": 1505162126870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.327667, 46.1355, 6.01 ] } }, +{ "type": "Feature", "properties": { "id": "ak16818311", "mag": 2.4, "time": 1505162030333, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -167.0, 53.2916, 13.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16818304", "mag": 2.2, "time": 1505161796041, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -167.8204, 65.319, 3.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16818297", "mag": 2.0, "time": 1505161193751, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8659, 62.8899, 99.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16818278", "mag": 3.2, "time": 1505160763887, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.115, 63.145, 108.2 ] } }, +{ "type": "Feature", "properties": { "id": "mb80254694", "mag": 1.38, "time": 1505160716790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.540833, 46.904833, 11.87 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akaa", "mag": 2.5, "time": 1505159932140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4306, 42.5727, 7.14 ] } }, +{ "type": "Feature", "properties": { "id": "mb80254684", "mag": 1.16, "time": 1505159186030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.524833, 46.8675, 11.01 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827348", "mag": 1.2, "time": 1505158596706, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2022, 60.4231, 48.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16817479", "mag": 2.9, "time": 1505158124591, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.5505, 65.8017, 12.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16817476", "mag": 3.0, "time": 1505158119494, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.2439, 66.0161, 16.1 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604719", "mag": 1.3, "time": 1505157785095, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8838, 38.8119, 4.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890441", "mag": 1.74, "time": 1505157705880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.778, 38.7915, 3.48 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak9n", "mag": 3.0, "time": 1505157604550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.471, 42.609, 7.61 ] } }, +{ "type": "Feature", "properties": { "id": "ak16817472", "mag": 1.1, "time": 1505156621773, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3067, 62.9071, 5.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827345", "mag": 1.6, "time": 1505156304521, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.3368, 59.849, 84.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16816710", "mag": 1.0, "time": 1505155839711, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.7252, 63.4914, 1.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827343", "mag": 1.6, "time": 1505155190108, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.9414, 58.9343, 71.6 ] } }, +{ "type": "Feature", "properties": { "id": "uu60243377", "mag": 2.04, "time": 1505154917000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.423167, 42.524333, 7.67 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak8v", "mag": 4.8, "time": 1505154337990, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 125.9192, 10.9561, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827342", "mag": 1.4, "time": 1505154205074, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0563, 59.7893, 104.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akih", "mag": 3.5, "time": 1505153371450, "felt": 12, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -8.5745, 37.1247, 19.99 ] } }, +{ "type": "Feature", "properties": { "id": "ak16816675", "mag": 2.0, "time": 1505153241938, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.1793, 60.2771, 148.8 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604702", "mag": 1.1, "time": 1505152546779, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8175, 38.8318, 9.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890416", "mag": 1.57, "time": 1505151412520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8205, 37.474, -0.34 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak7u", "mag": 5.7, "time": 1505151309620, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 142.3373, 23.9529, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak7m", "mag": 2.5, "time": 1505151089130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4259, 42.5401, 6.8 ] } }, +{ "type": "Feature", "properties": { "id": "mb80254649", "mag": 1.0, "time": 1505150945110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.515833, 46.859, 13.54 ] } }, +{ "type": "Feature", "properties": { "id": "ak16815885", "mag": 1.4, "time": 1505150387657, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8119, 60.5833, 13.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci37760231", "mag": 1.15, "time": 1505150078250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.339833, 33.717167, -0.52 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar17", "mag": 4.5, "time": 1505148873550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -27.1014, -58.1449, 29.22 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar14", "mag": 4.7, "time": 1505148316830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 141.7999, 10.8571, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak6r", "mag": 4.4, "time": 1505148294180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 93.763, 11.1912, 135.46 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar16", "mag": 4.3, "time": 1505147708500, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 105.5216, 28.9426, 37.11 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak65", "mag": 5.0, "time": 1505146815920, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 21.5733, 39.2104, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "uu60012999", "mag": 2.37, "time": 1505146629690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.425833, 42.545833, 6.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak62", "mag": 3.2, "time": 1505146591940, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4221, 42.5774, 8.61 ] } }, +{ "type": "Feature", "properties": { "id": "ci37760191", "mag": 1.27, "time": 1505146302070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.870333, 36.5125, 7.71 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar11", "mag": 4.2, "time": 1505146234900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 169.8301, -18.5966, 222.96 ] } }, +{ "type": "Feature", "properties": { "id": "ci37760183", "mag": 1.04, "time": 1505146087980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.721333, 33.538833, 2.61 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak5l", "mag": 4.4, "time": 1505145120270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.9232, 15.0128, 54.55 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827338", "mag": 1.8, "time": 1505144756285, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.3358, 57.9354, 144.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak5f", "mag": 4.3, "time": 1505144492050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0414, 15.1729, 45.88 ] } }, +{ "type": "Feature", "properties": { "id": "ak16815056", "mag": 1.9, "time": 1505144205558, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.6743, 59.7685, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak58", "mag": 3.1, "time": 1505144033150, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4647, 42.6086, 4.31 ] } }, +{ "type": "Feature", "properties": { "id": "uu60243162", "mag": 1.47, "time": 1505143989150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.462833, 42.578167, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16815038", "mag": 1.9, "time": 1505143851904, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.7738, 62.154, 53.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16815036", "mag": 1.9, "time": 1505143815664, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0859, 60.2049, 139.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak57", "mag": 4.8, "time": 1505143793430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 169.1802, 54.2242, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak55", "mag": 4.3, "time": 1505143224640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 146.6506, -2.821, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak4j", "mag": 3.0, "time": 1505142692750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4148, 42.5413, 9.05 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak4f", "mag": 4.4, "time": 1505142409640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0513, 14.8747, 44.09 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak40", "mag": 5.0, "time": 1505141758490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.3653, 15.3524, 32.65 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar1h", "mag": 4.9, "time": 1505141691760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -176.0928, -23.8876, 37.16 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak3s", "mag": 4.2, "time": 1505141169530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7122, 15.3112, 28.67 ] } }, +{ "type": "Feature", "properties": { "id": "mb80254604", "mag": 1.16, "time": 1505141014400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.532333, 46.8915, 13.58 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890356", "mag": 0.96, "time": 1505141002070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.819168, 38.845001, -0.69 ] } }, +{ "type": "Feature", "properties": { "id": "ak16814255", "mag": 2.0, "time": 1505140885717, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.2937, 51.4307, 40.1 ] } }, +{ "type": "Feature", "properties": { "id": "uw61306377", "mag": 1.82, "time": 1505140831500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.526167, 45.054, 14.59 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak3q", "mag": 4.2, "time": 1505140745590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4233, 15.4024, 50.36 ] } }, +{ "type": "Feature", "properties": { "id": "ci37760143", "mag": 1.15, "time": 1505140731290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.260667, 32.865667, 12.62 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890351", "mag": 1.47, "time": 1505140721900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.98, 37.905667, 7.94 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017254001", "mag": 1.99, "time": 1505140527660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.1661, 18.2745, 22.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak3b", "mag": 2.7, "time": 1505140375620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4329, 42.6048, 10.74 ] } }, +{ "type": "Feature", "properties": { "id": "uu60243057", "mag": 2.26, "time": 1505140157270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.440667, 42.570833, 6.17 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak35", "mag": 2.8, "time": 1505139740960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4268, 42.5293, 6.86 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar1f", "mag": 4.4, "time": 1505139719640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -33.2097, 57.3966, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak30", "mag": 2.8, "time": 1505139413770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4261, 42.5344, 6.18 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak2x", "mag": 2.8, "time": 1505139156090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4192, 42.5317, 7.87 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890336", "mag": 1.18, "time": 1505138783780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.788833, 37.4565, 7.82 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak5e", "mag": 3.4, "time": 1505138730330, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4143, 42.5438, 7.19 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak2i", "mag": 2.7, "time": 1505138706230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4164, 42.5288, 7.13 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak2w", "mag": 4.2, "time": 1505138643370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 147.2941, 49.241, 567.61 ] } }, +{ "type": "Feature", "properties": { "id": "ak16813499", "mag": 2.0, "time": 1505138537316, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.7415, 61.4216, 18.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak25", "mag": 2.7, "time": 1505138348200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4259, 42.5325, 7.14 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar0y", "mag": 4.6, "time": 1505138171510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 95.9326, 17.4028, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16813481", "mag": 1.9, "time": 1505137989499, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.3857, 59.1724, 56.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak1y", "mag": 2.6, "time": 1505137521110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4339, 42.5419, 8.21 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak1r", "mag": 2.9, "time": 1505137114700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4362, 42.5456, 6.59 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak1m", "mag": 3.0, "time": 1505136985250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4366, 42.5476, 10.03 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar0x", "mag": 4.6, "time": 1505136879610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 94.6908, 22.421, 111.87 ] } }, +{ "type": "Feature", "properties": { "id": "ak16813475", "mag": 2.1, "time": 1505136538402, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -175.5913, 51.4481, 48.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak17", "mag": 4.7, "time": 1505136395640, "felt": 63, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4397, 42.547, 8.42 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar13", "mag": 4.3, "time": 1505136238290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.0316, -19.7635, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37760103", "mag": 1.09, "time": 1505136097380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.293, 35.087333, 5.54 ] } }, +{ "type": "Feature", "properties": { "id": "ak16812727", "mag": 2.6, "time": 1505135732771, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.9083, 64.6086, 14.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16812725", "mag": 1.1, "time": 1505135440719, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -142.9809, 60.2846, 15.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16812722", "mag": 1.3, "time": 1505135255673, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2227, 61.5128, 2.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604646", "mag": 1.4, "time": 1505134420760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.0108, 37.3174, 5.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890261", "mag": 1.53, "time": 1505134375000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.944, 37.596667, 2.35 ] } }, +{ "type": "Feature", "properties": { "id": "ak16812712", "mag": 1.2, "time": 1505134108855, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.0572, 63.3368, 5.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890256", "mag": 2.28, "time": 1505133958310, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.804, 37.487667, 2.35 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827325", "mag": 1.0, "time": 1505133922020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.6291, 68.5279, 7.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827324", "mag": 2.0, "time": 1505133892582, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 179.5495, 51.3476, 48.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak0e", "mag": 2.5, "time": 1505133857280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4384, 42.5522, 4.67 ] } }, +{ "type": "Feature", "properties": { "id": "uu60242837", "mag": 1.53, "time": 1505133790240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.424667, 42.5545, 3.92 ] } }, +{ "type": "Feature", "properties": { "id": "hv61904231", "mag": 1.21, "time": 1505133342610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.6145, 19.417333, 2.362 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak05", "mag": 4.1, "time": 1505133270220, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4421, 42.5481, 9.98 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak03", "mag": 2.7, "time": 1505133174850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4364, 42.5648, 8.56 ] } }, +{ "type": "Feature", "properties": { "id": "ak16812710", "mag": 1.0, "time": 1505133166684, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.8559, 62.6857, 65.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar0u", "mag": 4.2, "time": 1505133047670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -179.1594, -25.8043, 396.76 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604676", "mag": 1.2, "time": 1505132161656, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9061, 38.3603, 6.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16811973", "mag": 1.1, "time": 1505132086727, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.8547, 61.7247, 43.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16811972", "mag": 1.5, "time": 1505132009437, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3277, 62.9497, 102.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajzy", "mag": 2.5, "time": 1505131814160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4451, 42.6131, 6.65 ] } }, +{ "type": "Feature", "properties": { "id": "mb80254459", "mag": 2.11, "time": 1505131462070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.591167, 48.595333, 11.25 ] } }, +{ "type": "Feature", "properties": { "id": "ak16811969", "mag": 1.3, "time": 1505131136327, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.0317, 60.2939, 13.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci37760055", "mag": 1.58, "time": 1505130502980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.1345, 33.263, 3.81 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajzq", "mag": 3.0, "time": 1505130391090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4364, 42.5733, 9.58 ] } }, +{ "type": "Feature", "properties": { "id": "ak16811954", "mag": 3.1, "time": 1505130323357, "felt": 0, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.1197, 60.1444, 17.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar0t", "mag": 4.0, "time": 1505129120720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -176.0508, -16.1442, 368.85 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajzk", "mag": 4.5, "time": 1505129105150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -74.1346, -37.5234, 25.58 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890236", "mag": 2.17, "time": 1505128675290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.822, 37.459167, 1.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827315", "mag": 2.3, "time": 1505128561623, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -163.8371, 52.7853, 7.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16811944", "mag": 1.3, "time": 1505128093436, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.0565, 64.7051, 17.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16811204", "mag": 1.3, "time": 1505127768013, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -163.9834, 54.7566, 4.6 ] } }, +{ "type": "Feature", "properties": { "id": "hv61904116", "mag": 2.16, "time": 1505127753700, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.28183, 19.407, 0.02 ] } }, +{ "type": "Feature", "properties": { "id": "ci37760031", "mag": 2.03, "time": 1505127492210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.712, 33.879333, 13.03 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827311", "mag": 1.5, "time": 1505127421795, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.853, 59.6229, 96.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16811203", "mag": 1.3, "time": 1505127015264, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.6217, 68.5348, 1.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16811201", "mag": 1.5, "time": 1505126914844, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.1251, 64.9961, 18.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16811199", "mag": 1.6, "time": 1505125956806, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.5218, 65.7316, 2.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16811198", "mag": 1.6, "time": 1505125657616, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.3884, 53.8156, 54.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890226", "mag": 1.01, "time": 1505125359080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.753998, 38.790165, 3.35 ] } }, +{ "type": "Feature", "properties": { "id": "ci37760023", "mag": 1.32, "time": 1505125346420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.25, 34.0295, 14.73 ] } }, +{ "type": "Feature", "properties": { "id": "ci37760015", "mag": 1.79, "time": 1505125221750, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.210667, 33.964, 14.98 ] } }, +{ "type": "Feature", "properties": { "id": "ak16811192", "mag": 1.6, "time": 1505124596279, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -167.4191, 53.5639, 6.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajy4", "mag": 3.0, "time": 1505124017240, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4438, 42.5496, 7.43 ] } }, +{ "type": "Feature", "properties": { "id": "ak16811190", "mag": 1.5, "time": 1505123878146, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.2865, 60.4132, 89.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16811188", "mag": 1.0, "time": 1505123692728, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.3358, 61.5763, 29.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890206", "mag": 0.98, "time": 1505123643110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.747167, 37.409167, 5.32 ] } }, +{ "type": "Feature", "properties": { "id": "ak16811186", "mag": 1.6, "time": 1505123476693, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.8224, 59.7877, 2.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajxv", "mag": 2.9, "time": 1505123164250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4237, 42.5673, 7.37 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajxj", "mag": 4.3, "time": 1505122591560, "felt": 25, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4287, 42.5544, 2.24 ] } }, +{ "type": "Feature", "properties": { "id": "uu60242567", "mag": 2.2, "time": 1505122522080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4315, 42.546167, 6.37 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759983", "mag": 1.63, "time": 1505121892310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.268167, 34.059667, 16.34 ] } }, +{ "type": "Feature", "properties": { "id": "ak16810446", "mag": 2.6, "time": 1505121756650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.4598, 60.9205, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16810443", "mag": 1.2, "time": 1505121065274, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.565, 68.8276, 0.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759967", "mag": 1.22, "time": 1505119075410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.577833, 33.463, 8.81 ] } }, +{ "type": "Feature", "properties": { "id": "uw61306317", "mag": 1.48, "time": 1505118779800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.494333, 48.421333, 23.39 ] } }, +{ "type": "Feature", "properties": { "id": "uu60242517", "mag": 2.59, "time": 1505118734680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -109.851333, 41.686167, 9.37 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017254000", "mag": 3.41, "time": 1505118382390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.9758, 19.4726, 83.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16809713", "mag": 1.0, "time": 1505117722024, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.6659, 62.2481, 21.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16809711", "mag": 3.4, "time": 1505116920134, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -169.5449, 52.5632, 40.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajwn", "mag": 4.4, "time": 1505116663270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.9806, 15.3004, 56.84 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759959", "mag": 1.14, "time": 1505116447350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.2325, 33.327833, 10.93 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajwc", "mag": 2.7, "time": 1505116217360, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4585, 42.6238, 8.02 ] } }, +{ "type": "Feature", "properties": { "id": "uu60242452", "mag": 1.42, "time": 1505115184130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4215, 42.555167, 8.21 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajw6", "mag": 4.3, "time": 1505114696270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.1399, -24.246, 215.32 ] } }, +{ "type": "Feature", "properties": { "id": "ak16809708", "mag": 1.5, "time": 1505114006947, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8258, 60.1009, 45.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827294", "mag": 1.9, "time": 1505113098912, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -142.8676, 59.0889, 2.2 ] } }, +{ "type": "Feature", "properties": { "id": "mb80254374", "mag": 1.5, "time": 1505112921190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.529333, 46.8645, 12.3 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759927", "mag": 2.02, "time": 1505112772010, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.403, 34.906, 11.64 ] } }, +{ "type": "Feature", "properties": { "id": "ak16809693", "mag": 2.3, "time": 1505111147899, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -142.1691, 60.3968, 3.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890121", "mag": 1.12, "time": 1505109941490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.819168, 38.807335, 2.77 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajvf", "mag": 2.9, "time": 1505109741010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4688, 42.5774, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajva", "mag": 4.3, "time": 1505109063560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.9711, 15.3853, 85.78 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890106", "mag": 1.68, "time": 1505108835910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.298667, 36.839667, 6.48 ] } }, +{ "type": "Feature", "properties": { "id": "ak16809690", "mag": 2.3, "time": 1505108549578, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.9816, 56.0816, 4.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajv3", "mag": 2.5, "time": 1505108046520, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4343, 42.6729, 8.91 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajuy", "mag": 4.3, "time": 1505107771280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.0235, 15.4152, 96.62 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827288", "mag": 1.8, "time": 1505107165861, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.0716, 53.7182, 69.4 ] } }, +{ "type": "Feature", "properties": { "id": "uw61306307", "mag": 1.9, "time": 1505107163540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.039333, 46.874833, 6.58 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890096", "mag": 1.14, "time": 1505106775000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.0835, 41.351667, 6.69 ] } }, +{ "type": "Feature", "properties": { "id": "ak16809640", "mag": 2.4, "time": 1505106550298, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.8937, 61.0452, 165.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16808961", "mag": 1.6, "time": 1505105485577, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.1953, 59.1308, 77.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajuh", "mag": 4.0, "time": 1505105288350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.1177, 14.9912, 39.36 ] } }, +{ "type": "Feature", "properties": { "id": "uu60242387", "mag": 2.04, "time": 1505105195110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4145, 42.553333, 8.78 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759879", "mag": 1.88, "time": 1505105166860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.690333, 36.111167, 2.14 ] } }, +{ "type": "Feature", "properties": { "id": "uu60242382", "mag": 1.62, "time": 1505105133670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.917167, 39.7665, 0.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajua", "mag": 4.2, "time": 1505104652010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -95.1678, 15.2785, 67.46 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aju8", "mag": 4.3, "time": 1505104387690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 134.2896, -4.2452, 11.73 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aju4", "mag": 4.2, "time": 1505104376590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.8401, 15.5681, 47.06 ] } }, +{ "type": "Feature", "properties": { "id": "ak16808959", "mag": 1.5, "time": 1505103598244, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.9778, 58.2872, 74.3 ] } }, +{ "type": "Feature", "properties": { "id": "uw61306297", "mag": 2.04, "time": 1505103582560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.041833, 46.873833, 6.67 ] } }, +{ "type": "Feature", "properties": { "id": "uw61306292", "mag": 2.25, "time": 1505103114370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.041333, 46.872667, 6.52 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827283", "mag": 1.6, "time": 1505102962401, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.439, 59.7864, 127.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827279", "mag": 1.3, "time": 1505101851739, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.7785, 59.9173, 97.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar0i", "mag": 4.1, "time": 1505101626150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 152.4651, -10.314, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759855", "mag": 1.09, "time": 1505101001790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.693833, 36.111833, 2.19 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajtf", "mag": 3.6, "time": 1505100425300, "felt": 34, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -96.7392, 35.5637, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar0g", "mag": 4.3, "time": 1505099718750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -33.3922, 57.1877, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16808239", "mag": 1.2, "time": 1505099609741, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.1984, 60.4559, 13.3 ] } }, +{ "type": "Feature", "properties": { "id": "mb80254349", "mag": 1.33, "time": 1505099352010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.536833, 46.868167, 13.72 ] } }, +{ "type": "Feature", "properties": { "id": "ak16808202", "mag": 1.5, "time": 1505098597935, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.3852, 59.9636, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16808197", "mag": 1.0, "time": 1505098478421, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2252, 63.2571, 2.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16808189", "mag": 2.2, "time": 1505098007693, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -137.7551, 60.3801, 2.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajt6", "mag": 3.1, "time": 1505097902820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -137.7475, 60.3735, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajt7", "mag": 5.1, "time": 1505097732030, "felt": null, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 134.3851, -4.1892, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16808181", "mag": 1.1, "time": 1505097584665, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6756, 61.6922, 62.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajt5", "mag": 3.0, "time": 1505097294300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4685, 42.672, 9.46 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajt2", "mag": 2.8, "time": 1505097280810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4535, 42.6306, 9.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar0e", "mag": 4.3, "time": 1505096741600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 122.0697, 24.7471, 68.23 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajsz", "mag": 4.7, "time": 1505096631090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9001, 15.6517, 51.53 ] } }, +{ "type": "Feature", "properties": { "id": "ak16807505", "mag": 1.3, "time": 1505096509471, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.9046, 61.531, 28.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16807502", "mag": 1.6, "time": 1505096282982, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -159.2586, 62.549, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890026", "mag": 1.21, "time": 1505096190960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.009667, 37.590833, -0.07 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajsw", "mag": 4.2, "time": 1505095770400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.418, 15.8113, 56.97 ] } }, +{ "type": "Feature", "properties": { "id": "ak16807468", "mag": 1.2, "time": 1505095529647, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.0357, 62.0888, 52.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759783", "mag": 2.05, "time": 1505095452510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.502333, 35.679, 6.19 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890021", "mag": 1.71, "time": 1505095034230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.535667, 37.632333, 19.33 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759775", "mag": 1.34, "time": 1505095022580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.507333, 34.488, 1.46 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajsk", "mag": 4.6, "time": 1505093529680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 143.5451, 12.9836, 114.29 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827267", "mag": 1.3, "time": 1505093440775, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.1537, 59.7401, 106.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759759", "mag": 1.69, "time": 1505093145730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.798167, 33.493667, 3.61 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604614", "mag": 1.5, "time": 1505092989312, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.6589, 37.3487, 6.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar1r", "mag": 3.5, "time": 1505092806050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 170.8111, 53.8607, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ar0b", "mag": 4.2, "time": 1505092783010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 95.953, 17.3198, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "hv61903861", "mag": 1.26, "time": 1505092321650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.490333, 19.339667, 9.09 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajsh", "mag": 4.1, "time": 1505092219210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 129.972, -6.9548, 134.48 ] } }, +{ "type": "Feature", "properties": { "id": "ak16806794", "mag": 1.3, "time": 1505092129494, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.3457, 60.4497, 89.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827265", "mag": 1.1, "time": 1505091880397, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6719, 63.2902, 124.6 ] } }, +{ "type": "Feature", "properties": { "id": "uu60242262", "mag": 2.47, "time": 1505091634360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.440667, 42.578333, 7.23 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajsf", "mag": 2.3, "time": 1505091431720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.443, 42.5904, 7.61 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827264", "mag": 1.3, "time": 1505091007359, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.0095, 58.5704, 86.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890011", "mag": 1.58, "time": 1505090685010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.832333, 37.542333, 4.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759743", "mag": 1.01, "time": 1505090624240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.589167, 36.0335, 2.63 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amxb", "mag": 3.0, "time": 1505090296990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.554, 51.5916, 17.56 ] } }, +{ "type": "Feature", "properties": { "id": "nc72890001", "mag": 0.97, "time": 1505089976320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.831, 37.541833, 4.79 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajsa", "mag": 4.9, "time": 1505089942200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.9938, 15.3932, 58.95 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajs1", "mag": 3.2, "time": 1505088752720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4151, 42.563, 8.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajrw", "mag": 4.4, "time": 1505087147130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.4901, 14.0924, 54.64 ] } }, +{ "type": "Feature", "properties": { "id": "ak16806048", "mag": 1.2, "time": 1505085946916, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.3481, 62.1328, 10.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759727", "mag": 1.54, "time": 1505085941950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.663167, 35.044, -0.82 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajrn", "mag": 2.4, "time": 1505085758040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4372, 42.584, 3.54 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827727", "mag": 1.2, "time": 1505085448361, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0012, 60.1398, 104.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajrh", "mag": 2.4, "time": 1505084625610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4614, 42.6018, 5.02 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajre", "mag": 3.0, "time": 1505084186000, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4583, 42.5935, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16805384", "mag": 1.3, "time": 1505084019928, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9225, 60.1912, 51.8 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017253006", "mag": 3.55, "time": 1505083663180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -68.7241, 19.5025, 24.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759703", "mag": 1.47, "time": 1505083414820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.164, 34.038833, 6.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759695", "mag": 2.37, "time": 1505083359860, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.166167, 34.037667, 6.01 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759687", "mag": 1.26, "time": 1505083316070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.166667, 34.039167, 6.08 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70234968", "mag": 1.57, "time": 1505083207900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.877167, 37.229167, 3.02 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759679", "mag": 1.03, "time": 1505082787240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.290167, 35.090833, 2.62 ] } }, +{ "type": "Feature", "properties": { "id": "uu60242127", "mag": 1.52, "time": 1505082515530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.439, 42.5855, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16805375", "mag": 2.0, "time": 1505082468672, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.2261, 62.1899, 53.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16805361", "mag": 2.4, "time": 1505082389962, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.8636, 68.2355, 2.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajq9", "mag": 3.3, "time": 1505081821360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4511, 42.5959, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889956", "mag": 1.01, "time": 1505081275110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.790333, 37.452833, 8.21 ] } }, +{ "type": "Feature", "properties": { "id": "ak16805341", "mag": 2.5, "time": 1505081090999, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.9101, 57.044, 46.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajpe", "mag": 5.9, "time": 1505079621210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -33.6765, 57.1272, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889936", "mag": 1.22, "time": 1505079295950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.937667, 37.601667, 1.02 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889931", "mag": 1.1, "time": 1505078962470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.806, 37.5175, -2.34 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajp8", "mag": 2.8, "time": 1505078892060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4509, 42.5792, 6.22 ] } }, +{ "type": "Feature", "properties": { "id": "uw61306227", "mag": 1.13, "time": 1505078465000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.011167, 46.792, 5.12 ] } }, +{ "type": "Feature", "properties": { "id": "uu60241997", "mag": 1.44, "time": 1505078100230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.422167, 42.554167, 8.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827720", "mag": 1.0, "time": 1505077902054, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.0938, 58.0932, 50.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889921", "mag": 1.74, "time": 1505077579730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.941333, 37.642833, 0.01 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889926", "mag": 1.62, "time": 1505077560070, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.946167, 37.638667, -0.65 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889911", "mag": 0.99, "time": 1505077390170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.394833, 36.9325, 8.56 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017253005", "mag": 2.52, "time": 1505077373570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -66.714, 18.0166, 7.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889916", "mag": 0.95, "time": 1505077317230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.881833, 37.512333, -0.07 ] } }, +{ "type": "Feature", "properties": { "id": "ak16804640", "mag": 1.6, "time": 1505077302019, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.5368, 58.8361, 122.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajnd", "mag": 4.5, "time": 1505076424950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2595, 15.0768, 55.96 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604604", "mag": 1.4, "time": 1505076297106, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.9555, 40.8314, 10.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16803984", "mag": 1.3, "time": 1505076289998, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1907, 63.4845, 0.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajms", "mag": 3.3, "time": 1505075535460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4239, 42.5436, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604570", "mag": 1.1, "time": 1505075507371, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.8807, 36.8036, 7.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827715", "mag": 1.2, "time": 1505074869438, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.7422, 60.0074, 102.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16803877", "mag": 1.0, "time": 1505074842648, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.4194, 63.2783, 7.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajm5", "mag": 2.5, "time": 1505074494700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4599, 42.5711, 10.61 ] } }, +{ "type": "Feature", "properties": { "id": "hv61903706", "mag": 1.86, "time": 1505074128010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.273331, 19.413166, 0.54 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajlx", "mag": 3.2, "time": 1505074034020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.42, 42.5453, 7.37 ] } }, +{ "type": "Feature", "properties": { "id": "ak16803869", "mag": 1.2, "time": 1505073920064, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.7217, 63.3651, 4.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajls", "mag": 4.3, "time": 1505073807210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -69.114, -23.6018, 85.28 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajlp", "mag": 4.6, "time": 1505073492510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 13.2839, 42.1689, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759623", "mag": 1.13, "time": 1505073299090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.162, 34.035333, 6.06 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajlc", "mag": 2.7, "time": 1505072667200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.6178, 36.1361, 5.301 ] } }, +{ "type": "Feature", "properties": { "id": "mb80254244", "mag": 1.15, "time": 1505072506030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.527667, 46.862667, 10.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akfw", "mag": 3.1, "time": 1505072325000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4094, 42.5488, 7.85 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajl5", "mag": 2.7, "time": 1505072221960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4249, 42.5451, 9.42 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889901", "mag": 1.7, "time": 1505072189820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.784833, 38.824667, 1.65 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889906", "mag": 1.54, "time": 1505072140190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.153, 37.129167, 12.33 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889891", "mag": 1.28, "time": 1505070945740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.891, 37.544167, 1.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16803197", "mag": 2.5, "time": 1505070454371, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -162.4505, 54.6854, 60.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajkd", "mag": 4.1, "time": 1505070312980, "felt": 41, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4177, 42.5563, 13.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889881", "mag": 1.58, "time": 1505069810220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.149, 37.1305, 12.32 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajkz", "mag": 2.4, "time": 1505069780800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4181, 42.5449, 7.46 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017253004", "mag": 3.24, "time": 1505069521610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -65.0411, 19.2021, 48.0 ] } }, +{ "type": "Feature", "properties": { "id": "hv61903656", "mag": 1.57, "time": 1505069138690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.104167, 19.329333, 5.178 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajjx", "mag": 2.9, "time": 1505068769580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4153, 42.5555, 7.28 ] } }, +{ "type": "Feature", "properties": { "id": "ak16802543", "mag": 1.6, "time": 1505068750842, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.6404, 58.5519, 66.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajju", "mag": 2.5, "time": 1505068746720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -104.9924, 37.0464, 6.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889876", "mag": 1.12, "time": 1505068188960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.315667, 36.955833, 7.62 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajjp", "mag": 2.3, "time": 1505068125580, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.1711, 35.6565, 7.54 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajjl", "mag": 2.4, "time": 1505067921890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4388, 42.6003, 7.21 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759607", "mag": 1.53, "time": 1505067791950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.169667, 34.037167, 4.29 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759599", "mag": 0.99, "time": 1505067584720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.163333, 34.028, 2.94 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajn9", "mag": 2.7, "time": 1505067322220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -170.5732, 52.3355, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827705", "mag": 1.3, "time": 1505067315004, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.7536, 59.2097, 68.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889866", "mag": 1.0, "time": 1505067136160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.764168, 38.833, 0.66 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889861", "mag": 1.06, "time": 1505067131030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.759667, 38.833667, 1.17 ] } }, +{ "type": "Feature", "properties": { "id": "ak16802540", "mag": 1.3, "time": 1505066586033, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.3745, 62.1772, 42.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759591", "mag": 1.48, "time": 1505066404370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.166333, 34.044667, 5.25 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759583", "mag": 1.53, "time": 1505066395290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.163333, 34.041167, 5.54 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827703", "mag": 1.0, "time": 1505066200905, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.7529, 58.6862, 17.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759567", "mag": 1.34, "time": 1505066082610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.163833, 34.040667, 6.08 ] } }, +{ "type": "Feature", "properties": { "id": "ak16802539", "mag": 1.1, "time": 1505065957419, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0268, 60.5262, 19.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajjb", "mag": 2.5, "time": 1505065916650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4209, 42.5639, 8.61 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759559", "mag": 1.32, "time": 1505065772840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.2325, 34.474333, 11.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16802537", "mag": 1.3, "time": 1505065364910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.2942, 63.1472, 1.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759551", "mag": 1.1, "time": 1505065150010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.172667, 34.034333, 5.23 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759543", "mag": 1.69, "time": 1505064387890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.295, 35.088667, 4.44 ] } }, +{ "type": "Feature", "properties": { "id": "ak16802513", "mag": 1.5, "time": 1505064158942, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -145.1889, 65.0868, 19.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajj3", "mag": 4.4, "time": 1505063935670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 82.4969, 41.9157, 28.96 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajiy", "mag": 2.7, "time": 1505063902750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4577, 42.6058, 5.68 ] } }, +{ "type": "Feature", "properties": { "id": "uu60241602", "mag": 1.36, "time": 1505063711640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.415333, 42.567, 9.66 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759535", "mag": 1.1, "time": 1505063618920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.165167, 34.041667, 6.46 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889821", "mag": 1.62, "time": 1505063575750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.157167, 37.135667, 10.29 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889816", "mag": 1.01, "time": 1505063492860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.774667, 35.547833, 5.09 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759527", "mag": 2.15, "time": 1505063398380, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.238167, 34.467833, 11.17 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajih", "mag": 2.5, "time": 1505062945810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4296, 42.5627, 11.62 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889806", "mag": 2.49, "time": 1505062781340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.801833, 38.789333, 3.19 ] } }, +{ "type": "Feature", "properties": { "id": "uu60013054", "mag": 1.65, "time": 1505062641290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.444, 42.594667, 6.67 ] } }, +{ "type": "Feature", "properties": { "id": "uu60241572", "mag": 2.02, "time": 1505062621720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.432167, 42.5965, 4.48 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759519", "mag": 1.59, "time": 1505062248460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.167, 34.038667, 4.49 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759511", "mag": 1.92, "time": 1505062179580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.165, 34.039333, 4.98 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759503", "mag": 1.57, "time": 1505062145210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.164167, 34.037667, 5.25 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759495", "mag": 1.42, "time": 1505061900480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.165667, 34.038667, 5.34 ] } }, +{ "type": "Feature", "properties": { "id": "ak16801882", "mag": 1.1, "time": 1505061849133, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -142.1509, 60.3803, 7.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759487", "mag": 1.49, "time": 1505061523920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.893, 35.343333, 5.39 ] } }, +{ "type": "Feature", "properties": { "id": "ak16801880", "mag": 1.5, "time": 1505061368254, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.731, 60.0161, 6.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759471", "mag": 1.2, "time": 1505061266330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.167333, 34.040167, 4.42 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajn8", "mag": 3.4, "time": 1505060976520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -173.3264, 52.5377, 96.17 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759455", "mag": 1.41, "time": 1505060968220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.8935, 35.3405, 5.83 ] } }, +{ "type": "Feature", "properties": { "id": "ak16801858", "mag": 1.5, "time": 1505060123211, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4433, 51.6859, 21.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16801272", "mag": 1.1, "time": 1505059792074, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.1384, 63.4871, 1.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827692", "mag": 2.2, "time": 1505059542515, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -169.3922, 52.3983, 21.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889781", "mag": 1.29, "time": 1505059412980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.943667, 37.596167, 2.31 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajqf", "mag": 4.6, "time": 1505058668170, "felt": 49, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 139.1945, 35.7377, 54.25 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889766", "mag": 1.32, "time": 1505058489100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.046333, 38.9295, 0.46 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajhi", "mag": 2.5, "time": 1505058212500, "felt": 9, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -96.7958, 35.9926, 4.398 ] } }, +{ "type": "Feature", "properties": { "id": "ak16801236", "mag": 1.4, "time": 1505058208151, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.9025, 57.4691, 48.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759407", "mag": 1.83, "time": 1505057535880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.3395, 34.014333, 2.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000artt", "mag": 4.2, "time": 1505057483820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 141.9272, 37.8866, 41.94 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827688", "mag": 1.7, "time": 1505057440690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.7035, 58.208, 3.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajh6", "mag": 4.6, "time": 1505057331420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4383, 15.2976, 42.92 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajh4", "mag": 2.6, "time": 1505057207380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4289, 42.5593, 7.96 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827687", "mag": 1.5, "time": 1505057001386, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4181, 51.7014, 6.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajh2", "mag": 4.2, "time": 1505056916120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2576, 14.9344, 12.93 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajgy", "mag": 2.5, "time": 1505056755330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.7823, 37.3283, 5.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827686", "mag": 1.1, "time": 1505056731493, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.8679, 57.3821, 46.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajgx", "mag": 2.8, "time": 1505056639060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4498, 42.5804, 5.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827685", "mag": 1.2, "time": 1505056471867, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.1402, 60.9584, 19.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajgu", "mag": 2.5, "time": 1505056401260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4462, 42.5738, 5.62 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajgm", "mag": 4.9, "time": 1505055545760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 146.6784, 14.1109, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759383", "mag": 1.0, "time": 1505055131400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.169167, 34.0425, 5.43 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajge", "mag": 3.4, "time": 1505054862840, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4185, 42.5625, 9.41 ] } }, +{ "type": "Feature", "properties": { "id": "ak16800620", "mag": 1.1, "time": 1505054600546, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.7386, 61.4915, 80.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajgc", "mag": 3.1, "time": 1505054298370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4151, 42.55, 7.52 ] } }, +{ "type": "Feature", "properties": { "id": "ak16800576", "mag": 2.5, "time": 1505054208776, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9361, 60.2731, 64.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889746", "mag": 1.38, "time": 1505053809310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.442, 37.695667, 4.15 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017253003", "mag": 2.17, "time": 1505052857240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.2868, 18.1121, 18.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajg9", "mag": 2.9, "time": 1505052838460, "felt": 11, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5162, 46.8743, 14.72 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889741", "mag": 1.38, "time": 1505052751930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.824333, 38.060667, 1.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16799977", "mag": 1.0, "time": 1505052033903, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.8767, 61.5617, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "mb80254079", "mag": 1.59, "time": 1505051737640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.410667, 44.4485, 6.72 ] } }, +{ "type": "Feature", "properties": { "id": "ak16799971", "mag": 1.7, "time": 1505051381698, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.7235, 59.8179, 4.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajfa", "mag": 4.3, "time": 1505051330480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -90.3498, 13.069, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajf7", "mag": 4.0, "time": 1505050961060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.3526, 52.4771, 237.56 ] } }, +{ "type": "Feature", "properties": { "id": "ak16799942", "mag": 1.7, "time": 1505050892677, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.6731, 59.5546, 120.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajf3", "mag": 4.6, "time": 1505050808670, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.529, 15.6631, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajf0", "mag": 4.5, "time": 1505050687090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4173, 15.2922, 52.65 ] } }, +{ "type": "Feature", "properties": { "id": "us2000artu", "mag": 4.1, "time": 1505050610220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 128.1836, -7.5542, 159.39 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajex", "mag": 4.3, "time": 1505049954620, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.6306, 15.7653, 20.71 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759303", "mag": 1.26, "time": 1505049848270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.7985, 33.504667, 4.53 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajeq", "mag": 2.8, "time": 1505049297970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4232, 42.5578, 7.16 ] } }, +{ "type": "Feature", "properties": { "id": "ak16799353", "mag": 1.3, "time": 1505049096103, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.6348, 59.8194, 14.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajen", "mag": 3.0, "time": 1505048991180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4182, 42.5509, 7.02 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827673", "mag": 1.6, "time": 1505048796797, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -167.3116, 53.3278, 13.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajej", "mag": 2.6, "time": 1505048615320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4688, 42.6115, 6.14 ] } }, +{ "type": "Feature", "properties": { "id": "mb80254034", "mag": 1.41, "time": 1505048540860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.521667, 46.8615, 12.53 ] } }, +{ "type": "Feature", "properties": { "id": "mb80254029", "mag": 1.23, "time": 1505048399750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.521167, 46.853, 11.49 ] } }, +{ "type": "Feature", "properties": { "id": "ak16799346", "mag": 2.0, "time": 1505048306207, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.2292, 62.187, 56.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aje5", "mag": 4.4, "time": 1505047810980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -87.8604, 12.4905, 60.22 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aje3", "mag": 3.6, "time": 1505047519260, "felt": 5, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4283, 42.5536, 6.44 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aje1", "mag": 2.8, "time": 1505047427230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4487, 42.6011, 5.82 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajdz", "mag": 2.5, "time": 1505047141140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4433, 42.6033, 3.94 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajm3", "mag": 3.4, "time": 1505046945740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -169.4897, 52.4554, 37.93 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajdq", "mag": 3.1, "time": 1505046464560, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4503, 42.6011, 4.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827668", "mag": 1.6, "time": 1505046395510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.3819, 59.8907, 133.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajdf", "mag": 3.9, "time": 1505045951750, "felt": 7, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4091, 42.5736, 10.02 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajdd", "mag": 3.1, "time": 1505045857190, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4617, 42.6284, 4.97 ] } }, +{ "type": "Feature", "properties": { "id": "uu60241107", "mag": 2.14, "time": 1505045641970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.427, 42.59, 6.81 ] } }, +{ "type": "Feature", "properties": { "id": "ak16798742", "mag": 1.3, "time": 1505045327481, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.3496, 69.231, 1.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajd9", "mag": 4.3, "time": 1505045213250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.1554, 14.0483, 13.91 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajd2", "mag": 4.5, "time": 1505044829750, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.4915, 15.8549, 21.45 ] } }, +{ "type": "Feature", "properties": { "id": "ak16798732", "mag": 2.6, "time": 1505044761546, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.966, 59.8093, 102.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajcy", "mag": 2.6, "time": 1505044665510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.5652, 42.6019, 9.42 ] } }, +{ "type": "Feature", "properties": { "id": "us2000artq", "mag": 4.4, "time": 1505044070510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 120.6016, 12.9144, 38.64 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827665", "mag": 1.6, "time": 1505043947734, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.3635, 51.6272, 0.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajci", "mag": 2.9, "time": 1505043647160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4487, 42.6201, 8.65 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827663", "mag": 2.1, "time": 1505043481292, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -168.5488, 52.6471, 37.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajch", "mag": 2.9, "time": 1505043441680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4464, 42.565, 8.31 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604506", "mag": 1.1, "time": 1505043238904, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.2044, 38.3052, 10.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajce", "mag": 2.6, "time": 1505042826200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4252, 42.5577, 5.15 ] } }, +{ "type": "Feature", "properties": { "id": "ak16798700", "mag": 1.7, "time": 1505042612937, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.2918, 69.235, 1.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajc9", "mag": 3.1, "time": 1505042537350, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4318, 42.5604, 7.18 ] } }, +{ "type": "Feature", "properties": { "id": "hv61903466", "mag": 2.42, "time": 1505042508060, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.211833, 19.916833, 13.349 ] } }, +{ "type": "Feature", "properties": { "id": "ak16798696", "mag": 1.3, "time": 1505042293807, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.3271, 69.2374, 3.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajbt", "mag": 4.7, "time": 1505041959050, "felt": 41, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4701, 42.6074, 4.56 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajbp", "mag": 2.6, "time": 1505041798510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4553, 42.6057, 2.2 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604588", "mag": 1.0, "time": 1505041736983, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8863, 39.0228, 11.8 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017253002", "mag": 2.88, "time": 1505041375350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -66.305, 18.603, 82.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajbk", "mag": 3.1, "time": 1505040789630, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4404, 42.601, 4.73 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajbj", "mag": 2.6, "time": 1505040635620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4423, 42.5705, 7.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759247", "mag": 1.02, "time": 1505040606370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.192167, 33.778, 3.52 ] } }, +{ "type": "Feature", "properties": { "id": "uw61306142", "mag": 2.37, "time": 1505040308500, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.040167, 46.875333, 6.45 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827659", "mag": 2.3, "time": 1505040202211, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -175.8004, 51.946, 193.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajba", "mag": 2.5, "time": 1505040116970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4234, 42.6126, 8.0 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70234948", "mag": 1.52, "time": 1505039824000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.878333, 37.226333, 2.17 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajay", "mag": 2.5, "time": 1505039717650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4475, 42.5965, 6.66 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759239", "mag": 1.83, "time": 1505039190870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.297667, 34.7275, 4.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759231", "mag": 1.46, "time": 1505038960010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.206167, 33.030167, 5.66 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajah", "mag": 4.9, "time": 1505038459290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5926, 15.8657, 62.07 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajad", "mag": 2.8, "time": 1505038317850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4649, 42.5713, 2.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ajac", "mag": 2.8, "time": 1505038143220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.3389, 42.5698, 5.91 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aja1", "mag": 2.5, "time": 1505037892850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4134, 42.5966, 2.41 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889666", "mag": 2.44, "time": 1505037177900, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.680333, 36.934833, 10.93 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ak98", "mag": 2.7, "time": 1505037007800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.9657, 36.5378, 5.921 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akbp", "mag": 3.5, "time": 1505036907810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4216, 42.6147, 2.61 ] } }, +{ "type": "Feature", "properties": { "id": "hv61903376", "mag": 2.02, "time": 1505036885770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.244, 19.404333, 38.634 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj9i", "mag": 5.0, "time": 1505036830570, "felt": 222, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4155, 42.5629, 9.83 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604494", "mag": 1.3, "time": 1505036614546, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9198, 38.3864, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16797541", "mag": 2.3, "time": 1505036483755, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -176.8674, 50.427, 38.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889656", "mag": 1.55, "time": 1505036419440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9445, 37.642333, -0.52 ] } }, +{ "type": "Feature", "properties": { "id": "us2000artp", "mag": 4.7, "time": 1505036336060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 147.742, 44.4006, 89.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj9e", "mag": 4.1, "time": 1505036045120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.8669, 15.7031, 37.36 ] } }, +{ "type": "Feature", "properties": { "id": "ak16797519", "mag": 3.3, "time": 1505035967489, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.9107, 62.993, 122.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16797515", "mag": 2.4, "time": 1505035289100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.6897, 53.169, 25.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827654", "mag": 1.4, "time": 1505034233691, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.9911, 60.3931, 86.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16796945", "mag": 2.3, "time": 1505033682313, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.0313, 60.3066, 10.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889646", "mag": 1.08, "time": 1505033636850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.818001, 38.801998, 2.52 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj8v", "mag": 2.4, "time": 1505033298010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.484, 42.6096, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amz2", "mag": 2.8, "time": 1505033251180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -163.0563, 54.0093, 14.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759175", "mag": 1.28, "time": 1505033174200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.362167, 33.154333, 11.24 ] } }, +{ "type": "Feature", "properties": { "id": "ak16796924", "mag": 1.8, "time": 1505033149645, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.7762, 53.453, 28.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj8s", "mag": 5.5, "time": 1505033064540, "felt": 15, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 142.8932, 41.7813, 45.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj8i", "mag": 5.2, "time": 1505032778170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5035, 15.7644, 57.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amz1", "mag": 2.8, "time": 1505032715690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -162.8991, 53.5788, 15.9 ] } }, +{ "type": "Feature", "properties": { "id": "mb80253749", "mag": 1.76, "time": 1505032545100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.524667, 46.889167, 14.06 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj87", "mag": 3.8, "time": 1505032481960, "felt": 5, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -104.9548, 37.0369, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000artm", "mag": 4.4, "time": 1505032427640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.852, -18.159, 601.21 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj86", "mag": 4.2, "time": 1505032314990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 22.3039, 38.0722, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759159", "mag": 0.97, "time": 1505031839650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.1615, 34.0365, 4.44 ] } }, +{ "type": "Feature", "properties": { "id": "us2000artk", "mag": 3.8, "time": 1505031830730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 170.788, 53.8251, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000amyz", "mag": 2.6, "time": 1505031468470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4988, 51.6871, 9.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arti", "mag": 4.5, "time": 1505031463320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 179.9123, -25.0133, 508.03 ] } }, +{ "type": "Feature", "properties": { "id": "hv61903321", "mag": 1.9, "time": 1505031307020, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.376, 19.109, 42.633 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759151", "mag": 2.32, "time": 1505031276490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.528667, 33.143833, 8.22 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889631", "mag": 1.68, "time": 1505031062020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.1025, 35.652333, 4.49 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759127", "mag": 0.99, "time": 1505030565890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.4795, 34.347667, 6.85 ] } }, +{ "type": "Feature", "properties": { "id": "ak16796357", "mag": 1.6, "time": 1505029768799, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.6864, 61.2792, 33.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16796347", "mag": 2.8, "time": 1505029738842, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8811, 62.6834, 89.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16796345", "mag": 1.1, "time": 1505029334941, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.9656, 62.9587, 88.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16796343", "mag": 1.4, "time": 1505028430485, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.3315, 60.2265, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759079", "mag": 1.03, "time": 1505028192380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.793833, 33.508, 4.77 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827644", "mag": 2.2, "time": 1505028185237, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -175.9799, 52.0013, 156.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000artg", "mag": 4.2, "time": 1505027908500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 179.9129, -24.5931, 503.92 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj7r", "mag": 4.5, "time": 1505027720310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5866, 15.1076, 24.87 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj7m", "mag": 3.3, "time": 1505027636400, "felt": 12, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -96.804, 35.9918, 5.961 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj7l", "mag": 3.0, "time": 1505027344470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4316, 42.5611, 7.33 ] } }, +{ "type": "Feature", "properties": { "id": "ak16796341", "mag": 1.6, "time": 1505026917606, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.9481, 51.2072, 22.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16796340", "mag": 1.2, "time": 1505026743356, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0079, 59.5892, 41.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16796338", "mag": 1.3, "time": 1505026513369, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.0949, 62.0857, 37.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759055", "mag": 1.58, "time": 1505026335940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.798333, 33.501167, 3.42 ] } }, +{ "type": "Feature", "properties": { "id": "mb80253734", "mag": 1.14, "time": 1505025721140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -113.170167, 47.328333, 19.23 ] } }, +{ "type": "Feature", "properties": { "id": "ak16796336", "mag": 1.0, "time": 1505025668896, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.2865, 62.4037, 46.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16796333", "mag": 1.6, "time": 1505025496149, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.8107, 60.5943, 2.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889606", "mag": 1.8, "time": 1505025336300, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.260333, 36.150833, 8.23 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj7g", "mag": 4.3, "time": 1505024815920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5354, 15.0816, 39.42 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827636", "mag": 1.3, "time": 1505024434533, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4031, 51.77, 19.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16795777", "mag": 1.4, "time": 1505024355978, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.0051, 60.2926, 12.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759039", "mag": 1.89, "time": 1505024281500, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.871, 36.511333, 7.6 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604470", "mag": 1.2, "time": 1505024158420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.1219, 37.3848, 6.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889576", "mag": 0.98, "time": 1505022995190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.766333, 37.576333, 4.92 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj75", "mag": 4.0, "time": 1505022687700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2661, 15.0962, 47.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827633", "mag": 1.4, "time": 1505022608119, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.9863, 59.5419, 87.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16795771", "mag": 1.7, "time": 1505022431855, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7645, 61.916, 63.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16795770", "mag": 1.2, "time": 1505022130505, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6083, 61.2662, 54.7 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604466", "mag": 1.4, "time": 1505021979344, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.1529, 37.0254, 0.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16795766", "mag": 1.7, "time": 1505021975648, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.1305, 61.3941, 3.7 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017253001", "mag": 2.14, "time": 1505021553530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.0151, 18.2211, 26.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37759015", "mag": 1.41, "time": 1505021428240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.1665, 34.037667, 5.07 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj6q", "mag": 2.8, "time": 1505020972500, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.6874, 36.6964, 8.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758999", "mag": 1.58, "time": 1505020355730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.168833, 34.037667, 4.71 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889556", "mag": 1.12, "time": 1505019834580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.712167, 38.750333, 2.07 ] } }, +{ "type": "Feature", "properties": { "id": "uw61306032", "mag": 2.05, "time": 1505019796720, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.038167, 46.874333, 6.38 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj6e", "mag": 4.1, "time": 1505019258690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -173.3705, 67.5564, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj6c", "mag": 4.1, "time": 1505019032690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -95.0925, 15.7467, 34.06 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ayew", "mag": 4.2, "time": 1505018634430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9037, 15.4311, 74.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758959", "mag": 1.24, "time": 1505018324480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.169833, 34.0395, 6.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16795206", "mag": 2.1, "time": 1505018157144, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.4944, 60.3044, 178.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ayer", "mag": 4.0, "time": 1505017700720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.8225, 15.3927, 47.72 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758935", "mag": 1.14, "time": 1505017497720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.169, 34.039333, 6.34 ] } }, +{ "type": "Feature", "properties": { "id": "ak16795202", "mag": 1.4, "time": 1505017366860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3287, 63.2644, 12.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758927", "mag": 0.97, "time": 1505017113210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.034167, 34.268333, -0.16 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827627", "mag": 1.4, "time": 1505017084382, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.915, 59.1941, 109.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758911", "mag": 1.67, "time": 1505016996470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.167, 34.037833, 5.81 ] } }, +{ "type": "Feature", "properties": { "id": "ak16795198", "mag": 1.2, "time": 1505016773648, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.4096, 62.1404, 0.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16795193", "mag": 2.2, "time": 1505016672191, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.3522, 59.8641, 133.9 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70234903", "mag": 1.63, "time": 1505016085390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.572167, 37.347167, 4.85 ] } }, +{ "type": "Feature", "properties": { "id": "ak16795191", "mag": 1.2, "time": 1505016021415, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.4153, 61.11, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj5p", "mag": 4.3, "time": 1505015407020, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 141.7252, 38.0198, 68.12 ] } }, +{ "type": "Feature", "properties": { "id": "ak16795189", "mag": 1.3, "time": 1505014815822, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.7877, 59.5199, 52.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889511", "mag": 1.11, "time": 1505014765900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.711998, 38.755501, 2.76 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj5f", "mag": 4.1, "time": 1505014246310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7509, 15.2659, 43.51 ] } }, +{ "type": "Feature", "properties": { "id": "ak16795181", "mag": 2.2, "time": 1505014149113, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.8561, 61.3045, 25.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16795185", "mag": 1.8, "time": 1505014144643, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.2491, 60.9757, 43.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj59", "mag": 4.1, "time": 1505013882540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -173.2187, 67.6427, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "uw61306007", "mag": 1.81, "time": 1505013085820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.600667, 43.836167, 3.82 ] } }, +{ "type": "Feature", "properties": { "id": "mb80253724", "mag": 1.18, "time": 1505012880400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.520333, 46.896167, 10.28 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj51", "mag": 5.8, "time": 1505012842340, "felt": 8, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5278, 15.3896, 29.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16794614", "mag": 1.5, "time": 1505011941254, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.0253, 66.769, 24.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16794611", "mag": 1.9, "time": 1505011477433, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.452, 60.9238, 15.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16794610", "mag": 2.3, "time": 1505010496180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 178.5196, 51.817, 106.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arv6", "mag": 4.0, "time": 1505010360400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9747, 15.1883, 59.97 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017253000", "mag": 2.65, "time": 1505009947880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.1073, 18.2203, 79.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj4r", "mag": 4.3, "time": 1505009855470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.3515, 14.9239, 35.26 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj4q", "mag": 2.4, "time": 1505009730390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.403, 42.6058, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16794604", "mag": 1.5, "time": 1505009566066, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.5055, 61.4008, 14.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj4m", "mag": 3.2, "time": 1505008832850, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4779, 42.6737, 2.46 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aye7", "mag": 3.9, "time": 1505008653110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.442, 15.7739, 41.92 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj4i", "mag": 4.2, "time": 1505008285900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.3811, 14.9456, 27.79 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827395", "mag": 1.0, "time": 1505008083507, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.7452, 63.1544, 9.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16794056", "mag": 1.8, "time": 1505007980655, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -137.9725, 59.1241, 13.0 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604443", "mag": 1.1, "time": 1505007942083, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9112, 38.3937, 7.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758839", "mag": 1.22, "time": 1505007033130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.383167, 33.193, 7.75 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827393", "mag": 1.2, "time": 1505006807930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.6807, 59.9356, 95.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj47", "mag": 4.1, "time": 1505005871300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.689, 16.7045, 39.46 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj44", "mag": 4.3, "time": 1505005501920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7157, 15.408, 32.22 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj41", "mag": 4.3, "time": 1505005103690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5751, 15.5308, 63.49 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj3z", "mag": 4.4, "time": 1505004749280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4987, 15.3526, 47.21 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj3t", "mag": 3.3, "time": 1505004389150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -129.358, 44.2464, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16793513", "mag": 2.3, "time": 1505004296412, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -143.3005, 58.2485, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16793511", "mag": 2.0, "time": 1505004250005, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.3901, 51.6935, 13.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj3m", "mag": 3.3, "time": 1505004159420, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -129.0417, 44.4745, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827390", "mag": 1.5, "time": 1505004153873, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.9635, 59.4036, 98.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16827388", "mag": 1.4, "time": 1505003603974, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4592, 51.7361, 18.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16793506", "mag": 1.5, "time": 1505003554878, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.5578, 62.0025, 41.6 ] } }, +{ "type": "Feature", "properties": { "id": "mb80253689", "mag": 0.96, "time": 1505003169140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.508667, 46.879833, 9.14 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj3k", "mag": 4.7, "time": 1505002421890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -172.5775, -16.7183, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16793503", "mag": 1.2, "time": 1505001653442, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.0694, 51.6811, 2.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj3c", "mag": 2.3, "time": 1505001525800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.427, 42.5803, 7.86 ] } }, +{ "type": "Feature", "properties": { "id": "hv61903041", "mag": 1.97, "time": 1505000788390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.501, 19.948333, 38.213 ] } }, +{ "type": "Feature", "properties": { "id": "ak16793502", "mag": 2.1, "time": 1505000595653, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -159.5442, 56.1065, 5.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj36", "mag": 3.3, "time": 1505000090270, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -129.0754, 44.3952, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889416", "mag": 1.43, "time": 1505000045060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.709167, 38.768333, 1.44 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889411", "mag": 1.18, "time": 1504999845050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.424167, 38.768, 7.71 ] } }, +{ "type": "Feature", "properties": { "id": "ak16793501", "mag": 1.0, "time": 1504999793486, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0175, 59.5958, 36.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16793499", "mag": 1.5, "time": 1504999218478, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.9885, 60.7112, 87.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823567", "mag": 1.5, "time": 1504999019129, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.3619, 57.7499, 9.3 ] } }, +{ "type": "Feature", "properties": { "id": "hv61903026", "mag": 1.83, "time": 1504999009760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.28717, 19.4025, 1.54 ] } }, +{ "type": "Feature", "properties": { "id": "ak16793495", "mag": 1.5, "time": 1504998539010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.1873, 63.1024, 94.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16793492", "mag": 1.9, "time": 1504998198191, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.4513, 66.9866, 0.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16793490", "mag": 1.1, "time": 1504998084010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3555, 64.9906, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000am0g", "mag": 2.9, "time": 1504997864050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -161.5776, 54.9813, 70.97 ] } }, +{ "type": "Feature", "properties": { "id": "us2000am0f", "mag": 3.0, "time": 1504997382330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -158.4861, 55.435, 25.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj2w", "mag": 2.6, "time": 1504996101810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4595, 42.6646, 8.07 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823560", "mag": 1.1, "time": 1504995586471, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.5516, 60.1674, 10.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj2g", "mag": 2.6, "time": 1504995580700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -99.3253, 36.95, 2.161 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889401", "mag": 1.53, "time": 1504995533070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.883167, 39.862333, 5.12 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj2p", "mag": 4.3, "time": 1504995471290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -73.6167, -36.1497, 25.35 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758743", "mag": 0.97, "time": 1504995032090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.927167, 35.897667, 6.49 ] } }, +{ "type": "Feature", "properties": { "id": "ak16792945", "mag": 1.9, "time": 1504994934423, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.6439, 60.0021, 159.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889396", "mag": 1.01, "time": 1504994309360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.744499, 38.774666, 1.39 ] } }, +{ "type": "Feature", "properties": { "id": "mb80253659", "mag": 1.35, "time": 1504994237270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.767667, 45.618, 0.67 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889391", "mag": 1.15, "time": 1504994059680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.4355, 39.501833, 12.05 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ayd8", "mag": 4.0, "time": 1504993547880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -95.0655, 15.7772, 34.99 ] } }, +{ "type": "Feature", "properties": { "id": "uu60240502", "mag": 1.28, "time": 1504993388650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.014167, 44.781833, 8.11 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889381", "mag": 1.37, "time": 1504992621690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.732833, 38.768167, 0.83 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889376", "mag": 1.64, "time": 1504992347010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.879, 39.861333, 5.75 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889366", "mag": 0.99, "time": 1504990736460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.712667, 38.913333, 2.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj18", "mag": 4.9, "time": 1504990247280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.6127, -27.7277, 147.22 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aksk", "mag": 2.8, "time": 1504990158400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -96.8073, 35.9883, 6.228 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj13", "mag": 3.1, "time": 1504990070700, "felt": 18, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -96.8015, 35.9914, 5.85 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arta", "mag": 4.2, "time": 1504989955640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -95.0828, 15.537, 19.56 ] } }, +{ "type": "Feature", "properties": { "id": "ak16792284", "mag": 1.6, "time": 1504989907169, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.0546, 60.3983, 79.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889356", "mag": 0.96, "time": 1504989514010, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.201333, 37.802667, 8.55 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823554", "mag": 1.4, "time": 1504989475242, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.8158, 59.9912, 96.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj0w", "mag": 2.8, "time": 1504989429400, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.5041, 36.2908, 8.103 ] } }, +{ "type": "Feature", "properties": { "id": "hv61902851", "mag": 1.98, "time": 1504989368750, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.279159, 19.391001, 0.54 ] } }, +{ "type": "Feature", "properties": { "id": "us2000art9", "mag": 4.4, "time": 1504989282650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5518, 15.0779, 35.94 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj0x", "mag": 4.2, "time": 1504989178220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.8925, 15.5513, 33.85 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj1p", "mag": 2.3, "time": 1504988963860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -158.4077, 55.6085, 30.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823552", "mag": 1.2, "time": 1504988912939, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.7854, 60.1774, 76.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj0r", "mag": 4.8, "time": 1504988774940, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.8055, 15.4862, 41.24 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823551", "mag": 1.5, "time": 1504988703567, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.6984, 60.153, 94.6 ] } }, +{ "type": "Feature", "properties": { "id": "hv61902831", "mag": 2.68, "time": 1504988541740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.446, 20.027167, 8.137 ] } }, +{ "type": "Feature", "properties": { "id": "uu60240472", "mag": 1.31, "time": 1504988346800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.206, 39.282333, -3.32 ] } }, +{ "type": "Feature", "properties": { "id": "hv61902821", "mag": 2.08, "time": 1504988052380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.281998, 19.411833, 2.05 ] } }, +{ "type": "Feature", "properties": { "id": "ak16791747", "mag": 1.2, "time": 1504986900345, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.4114, 60.0877, 56.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889346", "mag": 1.15, "time": 1504985576640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.723667, 38.753833, 1.93 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aizy", "mag": 4.4, "time": 1504984967070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.1285, 55.2452, 28.63 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823547", "mag": 2.3, "time": 1504984573262, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.2291, 50.8322, 17.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aizr", "mag": 2.3, "time": 1504983888120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4504, 42.6494, 10.91 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604425", "mag": 1.1, "time": 1504983732096, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8284, 38.06, 3.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16791198", "mag": 1.7, "time": 1504983607869, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.5288, 51.7278, 12.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889341", "mag": 1.77, "time": 1504983196540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.881, 38.833667, 2.0 ] } }, +{ "type": "Feature", "properties": { "id": "uu60240427", "mag": 2.17, "time": 1504983086160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.417167, 42.555833, 8.52 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aizg", "mag": 4.4, "time": 1504983043410, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4218, 15.787, 57.77 ] } }, +{ "type": "Feature", "properties": { "id": "hv61902716", "mag": 1.45, "time": 1504983007260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.274333, 18.915833, 7.212 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823545", "mag": 1.7, "time": 1504982688397, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -166.1975, 53.2518, 21.4 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604404", "mag": 2.1, "time": 1504981848383, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9058, 38.3558, 8.8 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889331", "mag": 1.22, "time": 1504981774440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.480833, 38.843833, 10.34 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aiz4", "mag": 4.4, "time": 1504981610170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 155.7383, 49.4785, 59.88 ] } }, +{ "type": "Feature", "properties": { "id": "ak16791190", "mag": 2.4, "time": 1504980782997, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.857, 67.7643, 14.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823543", "mag": 1.8, "time": 1504980266831, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4071, 51.6082, 9.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758695", "mag": 1.06, "time": 1504980028730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.307667, 34.0925, 16.16 ] } }, +{ "type": "Feature", "properties": { "id": "ak16791189", "mag": 1.3, "time": 1504980002277, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.043, 60.3576, 52.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aiyg", "mag": 4.4, "time": 1504979697800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.459, 15.3004, 36.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823541", "mag": 1.5, "time": 1504978178608, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.8616, 58.3062, 104.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aycf", "mag": 4.2, "time": 1504977766490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.1719, 15.1363, 19.92 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889311", "mag": 1.86, "time": 1504977631430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.621667, 39.523333, 4.94 ] } }, +{ "type": "Feature", "properties": { "id": "us2000am0a", "mag": 2.9, "time": 1504977007380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.3606, 51.5729, 20.05 ] } }, +{ "type": "Feature", "properties": { "id": "uw61305857", "mag": 1.96, "time": 1504976913320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.5835, 49.325, -0.06 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604394", "mag": 1.0, "time": 1504976713972, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.9184, 39.4189, 9.4 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604419", "mag": 1.0, "time": 1504976501919, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9128, 38.3555, 7.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823539", "mag": 1.7, "time": 1504975843554, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.3563, 51.6531, 13.1 ] } }, +{ "type": "Feature", "properties": { "id": "uu60240367", "mag": 1.09, "time": 1504975707090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.071, 44.717, 8.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16790653", "mag": 3.1, "time": 1504974617088, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.3417, 51.6239, 10.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16790654", "mag": 1.9, "time": 1504974537489, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -175.3148, 51.695, 47.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aix7", "mag": 4.4, "time": 1504974070040, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.1553, 15.4199, 68.05 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aix4", "mag": 2.7, "time": 1504973305730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4403, 42.5514, 9.99 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758639", "mag": 1.49, "time": 1504972882060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.274333, 33.977333, 4.89 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823535", "mag": 1.4, "time": 1504972779074, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.6619, 59.5746, 73.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16790651", "mag": 1.4, "time": 1504972583759, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.0742, 62.1419, 37.4 ] } }, +{ "type": "Feature", "properties": { "id": "hv61902621", "mag": 1.3, "time": 1504971779440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.013167, 19.393333, 2.338 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758631", "mag": 1.6, "time": 1504971677250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.497167, 32.741, 8.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16790130", "mag": 2.4, "time": 1504971409637, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4283, 51.6859, 9.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aiwm", "mag": 5.3, "time": 1504971008260, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.8484, 15.8296, 39.05 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889281", "mag": 1.07, "time": 1504970982380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.944833, 37.598167, 1.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aiwh", "mag": 4.8, "time": 1504970946650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5822, 15.0866, 46.84 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aiwe", "mag": 4.6, "time": 1504970869530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.9636, 15.3251, 65.27 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889276", "mag": 1.09, "time": 1504970812160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.855667, 37.658833, 2.53 ] } }, +{ "type": "Feature", "properties": { "id": "ak16790123", "mag": 2.1, "time": 1504970292620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.13, 51.4897, 41.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16790120", "mag": 1.2, "time": 1504968778296, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.3618, 61.0444, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aiw3", "mag": 4.1, "time": 1504968358930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.193, 15.2562, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16789598", "mag": 2.5, "time": 1504968226307, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7868, 63.1355, 123.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16789594", "mag": 1.9, "time": 1504968045372, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.7112, 60.6453, 16.4 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758615", "mag": 1.41, "time": 1504967951280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.275, 33.978333, 4.74 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823526", "mag": 1.9, "time": 1504967456812, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -160.4388, 54.8237, 32.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aivy", "mag": 4.2, "time": 1504967440700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.1556, 16.3217, 115.13 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823525", "mag": 1.4, "time": 1504967368293, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.6252, 59.9753, 101.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823524", "mag": 1.7, "time": 1504966965980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.7649, 56.8018, 3.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823523", "mag": 1.6, "time": 1504966219015, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.4826, 51.2597, 23.7 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889256", "mag": 1.03, "time": 1504966067680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.012333, 37.593667, 0.37 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604381", "mag": 2.3, "time": 1504966020076, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.3553, 40.6574, 6.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758607", "mag": 1.15, "time": 1504965758050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.386667, 33.320333, 5.46 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aivs", "mag": 2.6, "time": 1504965349760, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.431, 42.5704, 9.32 ] } }, +{ "type": "Feature", "properties": { "id": "mb80253559", "mag": 1.01, "time": 1504964725150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.785167, 43.612, -3.47 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823520", "mag": 2.0, "time": 1504964361277, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.4265, 54.015, 30.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823518", "mag": 1.4, "time": 1504963874108, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.0471, 60.762, 82.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16789076", "mag": 1.7, "time": 1504963420635, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.7554, 59.5701, 80.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aivg", "mag": 4.8, "time": 1504963319300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.118, 15.2555, 36.22 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aiva", "mag": 4.7, "time": 1504963129400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.9764, 15.3921, 63.93 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823516", "mag": 1.1, "time": 1504962479847, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.8765, 58.9325, 12.9 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70234863", "mag": 1.66, "time": 1504961953310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.8555, 37.210833, 3.69 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aiuu", "mag": 4.3, "time": 1504961286800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.1507, 15.2159, 54.84 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889151", "mag": 1.59, "time": 1504961182210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.2615, 36.143, 9.79 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823515", "mag": 1.3, "time": 1504960711273, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.5542, 59.755, 14.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aiud", "mag": 4.5, "time": 1504959908650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2891, 15.5969, 67.38 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823514", "mag": 2.3, "time": 1504959541727, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -158.2315, 55.4677, 18.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aiu3", "mag": 3.5, "time": 1504959495530, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.3875, 42.5392, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aiu8", "mag": 4.9, "time": 1504959466540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4075, 16.1573, 92.03 ] } }, +{ "type": "Feature", "properties": { "id": "ak16788555", "mag": 1.8, "time": 1504958775607, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.5009, 59.7863, 1.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823512", "mag": 1.2, "time": 1504958710011, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.6279, 61.013, 77.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aitr", "mag": 5.2, "time": 1504958620590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -66.1721, -22.4546, 222.22 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758559", "mag": 2.17, "time": 1504958517340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.871333, 36.511, 7.46 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889136", "mag": 1.89, "time": 1504958245210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.943333, 37.597, 2.4 ] } }, +{ "type": "Feature", "properties": { "id": "ak16788550", "mag": 1.2, "time": 1504957995087, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7877, 61.7723, 59.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aita", "mag": 3.9, "time": 1504957968370, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4749, 42.5793, 8.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aitc", "mag": 4.9, "time": 1504957853960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4489, 15.7338, 63.09 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889131", "mag": 1.42, "time": 1504957844330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.822667, 37.604833, 3.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ait9", "mag": 3.1, "time": 1504957715430, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4515, 42.5732, 7.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ait3", "mag": 3.0, "time": 1504956895100, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.7026, 36.641, 8.008 ] } }, +{ "type": "Feature", "properties": { "id": "us2000am03", "mag": 2.5, "time": 1504956200380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -163.0448, 53.9738, 19.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ait2", "mag": 4.0, "time": 1504956162220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.601, 15.854, 69.04 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aisv", "mag": 2.4, "time": 1504955702120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4242, 42.579, 6.95 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aisz", "mag": 4.5, "time": 1504955498600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 126.8292, 3.6504, 59.54 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889126", "mag": 1.04, "time": 1504955440550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.832333, 37.5415, 4.76 ] } }, +{ "type": "Feature", "properties": { "id": "ak16788046", "mag": 2.3, "time": 1504954557233, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.3602, 51.5792, 17.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aisn", "mag": 4.2, "time": 1504953867200, "felt": 0, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -70.2262, -15.3425, 224.81 ] } }, +{ "type": "Feature", "properties": { "id": "uu60240042", "mag": 1.27, "time": 1504953324130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.006167, 44.792, 10.46 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017252001", "mag": 2.09, "time": 1504953205290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.2761, 18.0591, 19.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758511", "mag": 1.45, "time": 1504952800930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.930333, 35.903, 6.17 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ayba", "mag": 4.1, "time": 1504952366970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5053, 15.7495, 68.22 ] } }, +{ "type": "Feature", "properties": { "id": "mb80253459", "mag": 1.52, "time": 1504952233330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.447, 46.021167, 0.93 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889121", "mag": 1.03, "time": 1504952209100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.871, 37.554833, 4.73 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758487", "mag": 1.12, "time": 1504952052150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.988, 36.408833, 5.76 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ais8", "mag": 4.3, "time": 1504951965100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 140.9766, 44.5128, 265.04 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604410", "mag": 1.1, "time": 1504951735991, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.3876, 37.2486, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758471", "mag": 1.08, "time": 1504951652550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.931667, 34.0345, 15.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16787530", "mag": 1.1, "time": 1504951610158, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.7897, 67.3419, 11.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ais3", "mag": 5.4, "time": 1504951518370, "felt": null, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 133.9356, -4.9459, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000airu", "mag": 4.6, "time": 1504951047220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.0237, -24.161, 169.64 ] } }, +{ "type": "Feature", "properties": { "id": "ak16787527", "mag": 1.5, "time": 1504950964134, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.1724, 62.5675, 9.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16787525", "mag": 1.4, "time": 1504950309819, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.6065, 60.0265, 7.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000am01", "mag": 3.8, "time": 1504950233710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -163.0371, 53.9395, 13.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889106", "mag": 1.8, "time": 1504950063660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.642667, 38.4305, 9.02 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ayb4", "mag": 3.9, "time": 1504949950000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -95.1532, 14.9116, 21.58 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889101", "mag": 1.84, "time": 1504949895770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.008833, 39.729667, 5.67 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823500", "mag": 1.6, "time": 1504949837453, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.187, 59.0211, 72.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823499", "mag": 1.5, "time": 1504949724642, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.0279, 61.4535, 96.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arsy", "mag": 4.1, "time": 1504949643990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 169.3876, -19.5742, 213.81 ] } }, +{ "type": "Feature", "properties": { "id": "ak16787519", "mag": 1.4, "time": 1504949316312, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.0341, 61.6767, 50.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823497", "mag": 2.2, "time": 1504949226805, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.3563, 55.6967, 21.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000airg", "mag": 2.3, "time": 1504948998980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4451, 42.6157, 5.99 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889066", "mag": 0.98, "time": 1504947621670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.982833, 37.917667, 10.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823496", "mag": 2.0, "time": 1504947486008, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -173.2987, 51.7726, 13.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16787403", "mag": 2.6, "time": 1504947413205, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.5944, 59.4202, 75.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aiqx", "mag": 4.1, "time": 1504946674160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5388, 15.3559, 54.35 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758415", "mag": 1.03, "time": 1504946346090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.892667, 32.718333, 8.72 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avsk", "mag": 2.8, "time": 1504946098400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4224, 42.5665, 6.74 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aiqt", "mag": 2.6, "time": 1504946086710, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4255, 42.5806, 6.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000avsj", "mag": 2.7, "time": 1504945947000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4298, 42.5744, 7.17 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ampk", "mag": 3.3, "time": 1504945822720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4585, 42.6108, 6.88 ] } }, +{ "type": "Feature", "properties": { "id": "us2000al9w", "mag": 3.6, "time": 1504945687860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4277, 42.5592, 9.39 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aiur", "mag": 4.0, "time": 1504945641000, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4155, 42.5631, 8.48 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823493", "mag": 1.8, "time": 1504945521703, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.5064, 51.8445, 13.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758407", "mag": 1.19, "time": 1504945503520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.470167, 34.3615, 1.96 ] } }, +{ "type": "Feature", "properties": { "id": "us2000akd5", "mag": 3.3, "time": 1504945430400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4221, 42.5799, 5.91 ] } }, +{ "type": "Feature", "properties": { "id": "us2000art2", "mag": 4.5, "time": 1504945418710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 145.5761, 18.7533, 262.64 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aiq7", "mag": 4.1, "time": 1504945384770, "felt": 32, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4167, 42.5619, 7.19 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aiql", "mag": 4.5, "time": 1504945169540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 130.0828, -6.9776, 133.54 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aiq2", "mag": 3.3, "time": 1504944298530, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.427, 42.5842, 7.06 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aipz", "mag": 4.8, "time": 1504944096330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0129, 15.2713, 53.97 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arsw", "mag": 4.7, "time": 1504943699570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -25.2724, -59.2757, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "hv61902241", "mag": 1.62, "time": 1504943455500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.2485, 19.386833, 31.012 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj4h", "mag": 2.6, "time": 1504943362330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4304, 42.5789, 7.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aipn", "mag": 4.2, "time": 1504943316560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 74.9524, 38.8091, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aipm", "mag": 2.3, "time": 1504943304230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4353, 42.5792, 9.03 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aipl", "mag": 2.8, "time": 1504942989430, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4364, 42.5726, 8.45 ] } }, +{ "type": "Feature", "properties": { "id": "us2000art3", "mag": 4.7, "time": 1504942625890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 146.7566, 13.8193, 16.98 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823489", "mag": 2.2, "time": 1504941981540, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.6119, 68.4897, 9.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16786898", "mag": 2.3, "time": 1504941973751, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.6435, 68.4109, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aipa", "mag": 4.1, "time": 1504940445840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7031, 15.6436, 38.39 ] } }, +{ "type": "Feature", "properties": { "id": "ak16786512", "mag": 1.4, "time": 1504940146158, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6116, 61.8175, 55.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758383", "mag": 1.42, "time": 1504940130810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.027333, 34.440333, 12.46 ] } }, +{ "type": "Feature", "properties": { "id": "uw61305607", "mag": 1.15, "time": 1504939688980, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.4665, 48.458667, 29.09 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604353", "mag": 1.1, "time": 1504939522222, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.9216, 38.3812, 6.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ayad", "mag": 4.2, "time": 1504939027620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4368, 15.1947, 59.18 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823487", "mag": 1.3, "time": 1504938992964, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.2717, 59.963, 19.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16786506", "mag": 2.6, "time": 1504938975370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.5829, 68.5268, 13.9 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758359", "mag": 1.28, "time": 1504938780620, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.4375, 32.7105, 7.58 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ayac", "mag": 4.2, "time": 1504938734260, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.6092, 15.0415, 60.74 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aip9", "mag": 4.8, "time": 1504938495700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.9169, 15.1747, 62.25 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aing", "mag": 5.0, "time": 1504938263510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7579, 15.8771, 50.37 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889046", "mag": 1.74, "time": 1504938239010, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.951833, 36.388167, 3.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758351", "mag": 1.69, "time": 1504938189230, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.433333, 32.708, 11.7 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758343", "mag": 2.17, "time": 1504938036110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.650333, 32.557, 11.77 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arsu", "mag": 4.2, "time": 1504937955720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.536, 15.7206, 33.37 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aya9", "mag": 4.1, "time": 1504937750680, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4987, 15.6186, 49.66 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ain2", "mag": 4.5, "time": 1504937531380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2803, 15.4532, 53.46 ] } }, +{ "type": "Feature", "properties": { "id": "mb80253349", "mag": 1.16, "time": 1504937527100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5255, 46.891167, 14.63 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aimz", "mag": 4.9, "time": 1504936574470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -25.7043, -59.8211, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aya4", "mag": 4.1, "time": 1504936122970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4429, 15.8428, 39.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823484", "mag": 1.2, "time": 1504936114606, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7939, 63.1602, 125.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16786077", "mag": 1.2, "time": 1504935774238, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.9696, 65.5175, 9.8 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604400", "mag": 1.2, "time": 1504935386919, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.5673, 40.9452, 13.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000alzw", "mag": 3.4, "time": 1504935359040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -170.4837, 52.2353, 39.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16786013", "mag": 1.4, "time": 1504934755508, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.2112, 59.8068, 77.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aimb", "mag": 4.7, "time": 1504934538770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7033, 15.6728, 51.46 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arum", "mag": 4.3, "time": 1504934315700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.6748, 15.2159, 35.55 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aim7", "mag": 4.0, "time": 1504934242180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.7794, 15.3776, 67.05 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aim0", "mag": 4.3, "time": 1504933783810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0338, 15.1325, 37.84 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay9t", "mag": 4.3, "time": 1504933351910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.8516, 15.6769, 64.29 ] } }, +{ "type": "Feature", "properties": { "id": "ak16785716", "mag": 1.3, "time": 1504933227428, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.6303, 68.5196, 9.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823479", "mag": 1.4, "time": 1504933167331, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.3862, 58.1118, 65.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823478", "mag": 1.9, "time": 1504932908497, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.2638, 51.342, 32.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ailq", "mag": 5.5, "time": 1504932892100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0613, 15.0808, 29.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ailp", "mag": 4.5, "time": 1504932819610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 119.1423, -8.6068, 144.45 ] } }, +{ "type": "Feature", "properties": { "id": "ak16785656", "mag": 1.7, "time": 1504932712383, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.238, 65.7544, 14.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72889011", "mag": 1.03, "time": 1504932679700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.051167, 36.471667, 6.53 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ailm", "mag": 2.9, "time": 1504932636140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.9441, 58.6028, 4.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay9s", "mag": 4.1, "time": 1504932576140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.6151, 15.175, 41.76 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ailg", "mag": 2.7, "time": 1504932451000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.5107, 36.2919, 8.117 ] } }, +{ "type": "Feature", "properties": { "id": "mb80253329", "mag": 1.19, "time": 1504932343290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.527833, 46.862667, 11.76 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758279", "mag": 1.67, "time": 1504932048030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.507167, 33.653, 1.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823475", "mag": 1.1, "time": 1504931942522, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.2765, 60.0722, 83.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aila", "mag": 4.2, "time": 1504931645090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4593, 15.3365, 41.87 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758271", "mag": 1.52, "time": 1504931420370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.8695, 34.238, 8.73 ] } }, +{ "type": "Feature", "properties": { "id": "ak16785521", "mag": 1.4, "time": 1504931241910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.646, 68.5258, 6.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16785582", "mag": 1.0, "time": 1504931175076, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.1393, 61.7136, 2.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ail5", "mag": 4.7, "time": 1504930943390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4341, 15.1257, 27.87 ] } }, +{ "type": "Feature", "properties": { "id": "ak16785423", "mag": 1.8, "time": 1504930589594, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.6499, 68.5284, 16.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16785419", "mag": 2.0, "time": 1504930533977, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.1907, 61.6985, 2.3 ] } }, +{ "type": "Feature", "properties": { "id": "nm60179177", "mag": 3.06, "time": 1504930529110, "felt": 135, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -87.913, 38.425, 11.76 ] } }, +{ "type": "Feature", "properties": { "id": "mb80253319", "mag": 1.63, "time": 1504930497770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.491667, 46.891833, 11.66 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay9p", "mag": 4.1, "time": 1504930486630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9352, 15.3169, 41.53 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay9n", "mag": 3.7, "time": 1504930165360, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5559, 15.8989, 56.13 ] } }, +{ "type": "Feature", "properties": { "id": "ak16785231", "mag": 2.5, "time": 1504929910494, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.6125, 68.5273, 8.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16785228", "mag": 2.4, "time": 1504929817958, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.6164, 68.5069, 15.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ail9", "mag": 4.2, "time": 1504929739110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2125, 15.079, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000alzs", "mag": 2.7, "time": 1504929498060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -169.2368, 51.9836, 19.57 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823467", "mag": 1.5, "time": 1504929296944, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.2744, 61.3017, 122.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay9h", "mag": 3.8, "time": 1504928398040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -95.0181, 16.0961, 38.88 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017252000", "mag": 3.08, "time": 1504928197450, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.4461, 18.7428, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay9g", "mag": 4.1, "time": 1504927088180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4711, 15.1531, 65.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16784944", "mag": 1.8, "time": 1504927005991, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.3303, 60.1916, 78.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16784941", "mag": 2.3, "time": 1504926969938, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.6189, 68.5221, 13.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16784938", "mag": 2.1, "time": 1504926585070, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.6431, 68.5555, 3.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aijy", "mag": 4.9, "time": 1504926495850, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.3472, 15.9092, 62.55 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay9f", "mag": 4.0, "time": 1504926311940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.338, 15.4947, 53.82 ] } }, +{ "type": "Feature", "properties": { "id": "ak16784757", "mag": 1.4, "time": 1504926151958, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.5619, 63.1355, 67.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay9d", "mag": 4.0, "time": 1504926060810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.644, 15.4622, 58.54 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay9b", "mag": 4.0, "time": 1504925827780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0747, 15.195, 43.36 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aj03", "mag": 2.7, "time": 1504925336910, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -163.2524, 54.0919, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aijm", "mag": 4.5, "time": 1504925090110, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -67.2748, -24.2322, 205.92 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aijl", "mag": 5.1, "time": 1504925024150, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7923, 15.6429, 57.68 ] } }, +{ "type": "Feature", "properties": { "id": "ak16784618", "mag": 2.6, "time": 1504924922956, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.6215, 68.5087, 13.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aij6", "mag": 4.9, "time": 1504924325880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2803, 15.0759, 19.62 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823460", "mag": 1.6, "time": 1504924009517, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.6908, 68.536, 4.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823459", "mag": 1.6, "time": 1504923856019, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.1588, 59.9206, 119.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758231", "mag": 1.09, "time": 1504923480190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.197667, 33.036667, 6.54 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823458", "mag": 1.2, "time": 1504923376066, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.8869, 60.0725, 77.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16784466", "mag": 1.3, "time": 1504922976851, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.9394, 63.4575, 10.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758223", "mag": 1.64, "time": 1504922815610, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.095167, 35.773167, 10.47 ] } }, +{ "type": "Feature", "properties": { "id": "uw61305517", "mag": 1.22, "time": 1504922472730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.234, 46.341167, 11.49 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758207", "mag": 0.96, "time": 1504922375210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.930333, 35.896833, 5.72 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823455", "mag": 1.1, "time": 1504921668573, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.5605, 58.7828, 14.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16784171", "mag": 1.5, "time": 1504921324109, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.7065, 68.5298, 8.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay97", "mag": 4.2, "time": 1504921245860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.8933, 15.7086, 79.65 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay95", "mag": 4.0, "time": 1504920659630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5492, 15.7942, 35.56 ] } }, +{ "type": "Feature", "properties": { "id": "ak16784114", "mag": 1.2, "time": 1504920524598, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.8278, 67.3421, 14.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823452", "mag": 1.3, "time": 1504919998366, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.593, 58.7481, 11.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arv3", "mag": 4.3, "time": 1504919742200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -82.4369, 7.7941, 13.81 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aiic", "mag": 4.1, "time": 1504919644420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.098, 15.37, 28.41 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888926", "mag": 1.51, "time": 1504919499600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.797167, 38.8195, 2.74 ] } }, +{ "type": "Feature", "properties": { "id": "hv61901901", "mag": 2.49, "time": 1504919482270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.300507, 19.404333, 13.76 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay91", "mag": 4.1, "time": 1504919175710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.5371, 15.6773, 67.69 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay90", "mag": 3.9, "time": 1504918842770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4561, 15.2969, 47.01 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888921", "mag": 1.43, "time": 1504918334270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.63, 40.262167, 3.32 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aiht", "mag": 4.4, "time": 1504918076900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5874, 15.6439, 12.93 ] } }, +{ "type": "Feature", "properties": { "id": "ak16783729", "mag": 1.5, "time": 1504917773363, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.7901, 64.8033, 13.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823450", "mag": 1.8, "time": 1504917198075, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.1288, 53.4202, 28.2 ] } }, +{ "type": "Feature", "properties": { "id": "uu60239577", "mag": 1.64, "time": 1504917186550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.438333, 42.574167, 3.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823449", "mag": 1.6, "time": 1504917085381, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.671, 59.1673, 61.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aihy", "mag": 4.1, "time": 1504916600330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.3911, 16.0661, 39.18 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aih9", "mag": 2.8, "time": 1504916318430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4281, 42.5718, 5.53 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aih8", "mag": 2.5, "time": 1504916278870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4338, 42.5822, 5.38 ] } }, +{ "type": "Feature", "properties": { "id": "ak16783588", "mag": 1.6, "time": 1504916071368, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.3277, 59.285, 86.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16783586", "mag": 1.1, "time": 1504915994737, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.056, 67.2634, 8.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823446", "mag": 2.1, "time": 1504915956900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -163.713, 53.9765, 25.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758159", "mag": 1.56, "time": 1504915633570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.2745, 33.978, 4.17 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arsl", "mag": 4.3, "time": 1504915283460, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.6805, 16.8287, 106.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16823445", "mag": 1.2, "time": 1504915279966, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -136.6323, 59.8055, 11.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16783409", "mag": 1.6, "time": 1504915272065, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.43, 61.3236, 75.8 ] } }, +{ "type": "Feature", "properties": { "id": "ci37164028", "mag": 1.71, "time": 1504915194240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.598333, 33.300667, 5.25 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758151", "mag": 2.09, "time": 1504915192060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.24, 32.322667, 6.67 ] } }, +{ "type": "Feature", "properties": { "id": "ak16783408", "mag": 1.6, "time": 1504915154515, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.3632, 60.1661, 90.3 ] } }, +{ "type": "Feature", "properties": { "id": "hv61901846", "mag": 1.94, "time": 1504914308880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.314, 18.895833, 12.72 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888886", "mag": 1.0, "time": 1504914139040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.003833, 37.588667, 1.64 ] } }, +{ "type": "Feature", "properties": { "id": "ak16783243", "mag": 1.1, "time": 1504913564223, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.2504, 62.3109, 15.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821920", "mag": 1.3, "time": 1504913498285, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.1821, 58.2348, 101.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821919", "mag": 1.4, "time": 1504913414028, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.1655, 60.5722, 86.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821918", "mag": 1.1, "time": 1504913077516, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.597, 58.7696, 12.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aigc", "mag": 4.1, "time": 1504912952040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.1585, 15.0785, 47.75 ] } }, +{ "type": "Feature", "properties": { "id": "uu60239522", "mag": 1.86, "time": 1504912091450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.417833, 42.557333, 7.29 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aifs", "mag": 4.4, "time": 1504911443790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 82.6815, 44.316, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16782938", "mag": 1.1, "time": 1504911183072, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3769, 64.9856, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16782937", "mag": 1.1, "time": 1504910876129, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -146.7587, 61.2722, 29.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16782871", "mag": 1.5, "time": 1504910569120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -139.4893, 60.1552, 7.8 ] } }, +{ "type": "Feature", "properties": { "id": "ak16782868", "mag": 1.4, "time": 1504910467245, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.7194, 62.6908, 57.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821913", "mag": 1.7, "time": 1504910258777, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.0231, 58.2214, 149.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888801", "mag": 1.9, "time": 1504909953040, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.8175, 37.486333, -0.46 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aif7", "mag": 2.5, "time": 1504909902600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.5076, 36.2848, 8.171 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aif4", "mag": 4.8, "time": 1504909723200, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.8865, 15.3302, 30.08 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821912", "mag": 1.1, "time": 1504909705310, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.3127, 62.4824, 115.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aif0", "mag": 3.0, "time": 1504909701800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.5069, 36.2872, 6.887 ] } }, +{ "type": "Feature", "properties": { "id": "mb80253249", "mag": 1.02, "time": 1504909626120, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.500333, 46.870333, 14.95 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888791", "mag": 1.37, "time": 1504909453970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.04, 37.6285, -2.07 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aier", "mag": 4.4, "time": 1504908895340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0113, 15.4861, 55.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821911", "mag": 1.3, "time": 1504908516343, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.8637, 60.6448, 52.5 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758063", "mag": 1.18, "time": 1504908189370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.201167, 33.035167, 5.64 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888781", "mag": 1.42, "time": 1504907868300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.038667, 37.624833, -2.91 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aie8", "mag": 4.7, "time": 1504907825570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5854, 15.5735, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888776", "mag": 1.8, "time": 1504907588830, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.040167, 37.63, -1.66 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aie6", "mag": 4.6, "time": 1504907582410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4976, 15.7473, 55.06 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aidm", "mag": 4.5, "time": 1504906777370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0707, 15.2209, 55.42 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aid9", "mag": 4.8, "time": 1504906287810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.3905, 15.4318, 56.37 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888771", "mag": 1.19, "time": 1504906092960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.451, 37.990333, 1.49 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aicx", "mag": 4.3, "time": 1504906074440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2669, 15.5886, 57.93 ] } }, +{ "type": "Feature", "properties": { "id": "ak16782412", "mag": 1.0, "time": 1504906074363, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.3787, 62.4883, 7.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16782375", "mag": 2.3, "time": 1504905457780, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -168.4787, 52.748, 40.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888756", "mag": 1.38, "time": 1504905314090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.756167, 39.273333, 4.85 ] } }, +{ "type": "Feature", "properties": { "id": "ak16782374", "mag": 1.2, "time": 1504905292993, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.8681, 59.9024, 67.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aicp", "mag": 4.2, "time": 1504905187950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4812, 15.6987, 35.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16782334", "mag": 1.1, "time": 1504904835105, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -144.7621, 65.5089, 13.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16782328", "mag": 2.5, "time": 1504904826453, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.811, 61.2391, 56.6 ] } }, +{ "type": "Feature", "properties": { "id": "uw61305342", "mag": 1.93, "time": 1504904598280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.065167, 44.442833, -1.58 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888751", "mag": 1.54, "time": 1504903192860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7535, 39.279333, 8.66 ] } }, +{ "type": "Feature", "properties": { "id": "ak16781999", "mag": 3.0, "time": 1504902403320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2239, 60.1717, 139.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16781990", "mag": 2.9, "time": 1504902403227, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2392, 60.1979, 145.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay7u", "mag": 4.1, "time": 1504902279690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7805, 15.528, 44.33 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821902", "mag": 2.3, "time": 1504902127057, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.6706, 53.1595, 47.8 ] } }, +{ "type": "Feature", "properties": { "id": "mb80253224", "mag": 1.28, "time": 1504901825890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.961667, 44.423667, 7.65 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758023", "mag": 1.23, "time": 1504901676790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.243333, 34.049667, 14.94 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arsf", "mag": 4.8, "time": 1504901654190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 169.1397, -18.9749, 151.93 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aib4", "mag": 4.7, "time": 1504901358420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4084, 14.947, 20.03 ] } }, +{ "type": "Feature", "properties": { "id": "mb80254729", "mag": 1.15, "time": 1504901142840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5325, 46.863333, 12.44 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arse", "mag": 4.2, "time": 1504900520170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 122.6478, 18.4195, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16781710", "mag": 1.5, "time": 1504900346639, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.5122, 61.5519, 57.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16781709", "mag": 1.3, "time": 1504900242686, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.7722, 60.316, 70.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aibq", "mag": 2.5, "time": 1504899687060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4383, 42.5694, 8.27 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888741", "mag": 1.05, "time": 1504899640660, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.013, 37.593167, 0.27 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aib3", "mag": 2.8, "time": 1504899556990, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4363, 42.571, 9.27 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aia5", "mag": 2.6, "time": 1504899482480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4289, 42.5733, 13.75 ] } }, +{ "type": "Feature", "properties": { "id": "ak16781595", "mag": 1.7, "time": 1504899244914, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -141.1502, 60.3533, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16781585", "mag": 3.9, "time": 1504899189169, "felt": 0, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.5601, 59.2544, 64.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37758007", "mag": 2.02, "time": 1504898829300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.561833, 31.0585, 5.61 ] } }, +{ "type": "Feature", "properties": { "id": "ak16781550", "mag": 1.4, "time": 1504898282611, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6296, 61.6699, 64.1 ] } }, +{ "type": "Feature", "properties": { "id": "ci37757991", "mag": 1.52, "time": 1504897913130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.184167, 34.008167, 14.79 ] } }, +{ "type": "Feature", "properties": { "id": "ci37757975", "mag": 1.23, "time": 1504897847890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.191833, 34.995167, -0.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai96", "mag": 4.7, "time": 1504897612480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.1128, 15.0427, 38.05 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay7g", "mag": 4.5, "time": 1504897486190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.6162, 15.5292, 52.13 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aku3", "mag": 2.7, "time": 1504897427450, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4362, 42.5723, 6.2 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aruj", "mag": 4.0, "time": 1504897268300, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 151.0589, 51.6006, 526.16 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai8x", "mag": 5.3, "time": 1504897044080, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9814, 16.231, 63.24 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ars7", "mag": 4.4, "time": 1504896441090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 166.9803, -12.2109, 239.13 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ars8", "mag": 4.2, "time": 1504895755810, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4237, 15.0921, 33.24 ] } }, +{ "type": "Feature", "properties": { "id": "ak16781202", "mag": 1.1, "time": 1504895394318, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.517, 62.887, 92.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai8l", "mag": 5.0, "time": 1504895053450, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -95.0247, 15.6158, 25.92 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888711", "mag": 1.13, "time": 1504894886190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.369, 37.616167, 3.76 ] } }, +{ "type": "Feature", "properties": { "id": "ci37757951", "mag": 1.29, "time": 1504894538140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.34, 35.0645, -0.97 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604251", "mag": 1.1, "time": 1504893693579, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.5283, 37.177, 14.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888696", "mag": 1.24, "time": 1504893681000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.9525, 37.9215, -0.25 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai89", "mag": 4.9, "time": 1504893629390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.339, 15.3801, 37.31 ] } }, +{ "type": "Feature", "properties": { "id": "ak16780971", "mag": 2.0, "time": 1504893338524, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.7656, 56.9755, 12.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai7x", "mag": 4.4, "time": 1504893167240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.8739, 15.6809, 69.44 ] } }, +{ "type": "Feature", "properties": { "id": "ci37757919", "mag": 1.09, "time": 1504892320190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.792333, 33.504167, 6.36 ] } }, +{ "type": "Feature", "properties": { "id": "ak16780872", "mag": 2.7, "time": 1504892251611, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.2184, 60.0235, 132.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai7w", "mag": 5.1, "time": 1504892136330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 54.7094, 14.7125, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16780870", "mag": 1.9, "time": 1504892114398, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.5364, 59.0829, 80.6 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604241", "mag": 1.7, "time": 1504892108096, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.8858, 39.5547, 16.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci37757903", "mag": 1.06, "time": 1504892000240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.084, 33.233167, 9.85 ] } }, +{ "type": "Feature", "properties": { "id": "mb80253164", "mag": 0.95, "time": 1504891992150, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.5415, 46.8995, 11.59 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai7p", "mag": 4.3, "time": 1504891955840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.495, 15.1404, 36.22 ] } }, +{ "type": "Feature", "properties": { "id": "ak16780841", "mag": 1.4, "time": 1504891846856, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.3249, 60.9139, 26.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arsh", "mag": 4.5, "time": 1504891333730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 133.2388, -6.8416, 19.98 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay6x", "mag": 4.1, "time": 1504891315080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7297, 15.3343, 19.17 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ars4", "mag": 4.4, "time": 1504891219920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 54.7693, 14.6837, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16780813", "mag": 1.5, "time": 1504891126668, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.153, 61.7092, 3.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888686", "mag": 1.23, "time": 1504891114230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.1045, 37.325167, -0.31 ] } }, +{ "type": "Feature", "properties": { "id": "ci37757879", "mag": 2.31, "time": 1504890797650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.463833, 34.355833, 3.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai73", "mag": 4.9, "time": 1504890172380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.6852, 15.6184, 20.97 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai6w", "mag": 4.8, "time": 1504890101520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.3813, 15.1628, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai6n", "mag": 4.6, "time": 1504889103890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 130.804, -6.0426, 126.88 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai6c", "mag": 4.7, "time": 1504888948510, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.8822, 15.7603, 70.11 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai66", "mag": 3.1, "time": 1504888942660, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4688, 42.6127, 7.46 ] } }, +{ "type": "Feature", "properties": { "id": "ci37757839", "mag": 1.07, "time": 1504888838380, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.931, 35.8975, 5.55 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai5r", "mag": 5.0, "time": 1504887559080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.1176, 15.3478, 50.28 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai7e", "mag": 2.6, "time": 1504887451250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.8013, 51.3347, 33.06 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai5q", "mag": 4.8, "time": 1504887267930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.834, 15.2659, 31.94 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ars1", "mag": 4.4, "time": 1504887163560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 121.5842, 0.5634, 87.49 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai5f", "mag": 4.9, "time": 1504887145160, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4164, 15.3325, 55.79 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aixn", "mag": 4.1, "time": 1504887139190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.237, 15.3669, 61.33 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821886", "mag": 1.0, "time": 1504887040916, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.7913, 61.8643, 40.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai53", "mag": 4.6, "time": 1504886882420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4908, 15.0663, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16780437", "mag": 1.7, "time": 1504886789015, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.1717, 61.2338, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arsa", "mag": 4.8, "time": 1504886367500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -45.1832, 25.2517, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arrz", "mag": 4.3, "time": 1504885790410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 121.1544, 13.7011, 115.66 ] } }, +{ "type": "Feature", "properties": { "id": "ci37757791", "mag": 2.49, "time": 1504885701960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.863167, 36.514, 1.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888591", "mag": 1.18, "time": 1504885591170, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.029167, 37.64, 1.33 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay69", "mag": 4.3, "time": 1504884967040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.8299, 15.2537, 51.49 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888561", "mag": 2.76, "time": 1504884687580, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -126.4015, 40.656167, 4.61 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888556", "mag": 1.22, "time": 1504884477720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.594833, 36.036167, 3.51 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888551", "mag": 1.29, "time": 1504884449700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.600833, 36.033, 2.98 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai45", "mag": 4.4, "time": 1504884249230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 51.6373, 29.0196, 32.54 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai4f", "mag": 5.0, "time": 1504884005650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -172.4529, -15.2805, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ci37757767", "mag": 1.56, "time": 1504883892090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.447333, 34.149, 10.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888536", "mag": 1.66, "time": 1504883570470, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.168167, 39.1465, -0.58 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arrw", "mag": 4.2, "time": 1504882974870, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7985, 15.5213, 35.36 ] } }, +{ "type": "Feature", "properties": { "id": "ak16779960", "mag": 1.8, "time": 1504882678981, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0626, 62.8988, 105.6 ] } }, +{ "type": "Feature", "properties": { "id": "ci37757743", "mag": 0.97, "time": 1504882082250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.499333, 33.723667, 12.91 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai3n", "mag": 5.3, "time": 1504881901650, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.3384, 15.544, 53.27 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai3i", "mag": 5.0, "time": 1504881612700, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4062, 15.406, 49.05 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai3c", "mag": 5.1, "time": 1504880703430, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.1626, 15.9178, 78.53 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821881", "mag": 1.9, "time": 1504880601665, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.7019, 53.1531, 4.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai3a", "mag": 4.6, "time": 1504880185590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.9379, 15.4789, 51.37 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888511", "mag": 1.64, "time": 1504879933970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.805, 37.519, 0.63 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arrt", "mag": 4.3, "time": 1504879797140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -92.5495, 15.2436, 49.04 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888506", "mag": 1.11, "time": 1504879682840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.807167, 37.5155, -1.34 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai2x", "mag": 4.4, "time": 1504878550770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.3291, 15.5119, 43.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai2u", "mag": 4.5, "time": 1504878237250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.3775, 15.3318, 55.57 ] } }, +{ "type": "Feature", "properties": { "id": "ak16779589", "mag": 2.1, "time": 1504878197682, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.7176, 61.7913, 43.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888501", "mag": 1.4, "time": 1504877974600, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.826833, 38.884833, 0.43 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai2s", "mag": 4.5, "time": 1504877794630, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2597, 15.3155, 57.11 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai2p", "mag": 4.3, "time": 1504877637550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.3617, 15.3594, 72.43 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821879", "mag": 1.1, "time": 1504877280981, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.4859, 62.9279, 91.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai2h", "mag": 4.3, "time": 1504877227420, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2794, 15.5765, 57.44 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai2d", "mag": 4.9, "time": 1504877000620, "felt": 5, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 140.4519, 39.5355, 14.54 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888491", "mag": 1.84, "time": 1504876384490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.493333, 38.505333, 9.95 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821878", "mag": 1.4, "time": 1504875984627, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.1326, 61.9648, 66.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821876", "mag": 2.2, "time": 1504875655387, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -168.9923, 52.3567, 17.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888486", "mag": 2.07, "time": 1504875297970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.476833, 38.505667, 10.55 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888481", "mag": 2.29, "time": 1504875261290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.487833, 38.504167, 11.24 ] } }, +{ "type": "Feature", "properties": { "id": "ak16779354", "mag": 1.2, "time": 1504874899621, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.8024, 62.2347, 27.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai1z", "mag": 4.7, "time": 1504874764610, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.9526, 15.348, 66.08 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604198", "mag": 1.6, "time": 1504874486416, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.1528, 36.3422, 12.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16779312", "mag": 1.1, "time": 1504874405501, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -142.2249, 66.2606, 1.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821873", "mag": 1.7, "time": 1504874360732, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -177.5174, 51.2619, 22.7 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604197", "mag": 1.1, "time": 1504874200883, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.2814, 37.8092, 5.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888476", "mag": 1.21, "time": 1504873957930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.509333, 40.482667, 4.94 ] } }, +{ "type": "Feature", "properties": { "id": "ci37757703", "mag": 1.39, "time": 1504873858920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.717833, 33.649333, 15.22 ] } }, +{ "type": "Feature", "properties": { "id": "ci37757695", "mag": 1.17, "time": 1504872471560, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.568167, 33.822667, 8.77 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai1k", "mag": 5.2, "time": 1504872379780, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4203, 15.4936, 64.61 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604195", "mag": 1.1, "time": 1504872342696, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.0794, 39.7864, 6.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai1f", "mag": 4.5, "time": 1504872210290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.752, 15.6687, 34.52 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai17", "mag": 4.7, "time": 1504871509040, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.251, 15.2604, 43.78 ] } }, +{ "type": "Feature", "properties": { "id": "ci37757687", "mag": 1.13, "time": 1504871201290, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.5185, 33.500333, 13.87 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai11", "mag": 4.8, "time": 1504870992430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5788, 16.0581, 67.6 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888461", "mag": 1.42, "time": 1504869975320, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.437833, 39.504833, 12.47 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai0u", "mag": 5.0, "time": 1504869955970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7875, 15.7988, 32.83 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888456", "mag": 1.91, "time": 1504869902080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.485667, 38.504833, 10.49 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai0r", "mag": 3.1, "time": 1504869744270, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4645, 42.6225, 8.36 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai0n", "mag": 4.5, "time": 1504869089530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4825, 15.1089, 36.59 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai0k", "mag": 4.3, "time": 1504868775480, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.798, 15.8932, 52.08 ] } }, +{ "type": "Feature", "properties": { "id": "ak16778868", "mag": 2.4, "time": 1504868579816, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.6965, 62.1823, 44.5 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888446", "mag": 1.29, "time": 1504868153570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.486333, 38.5055, 8.02 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888436", "mag": 1.9, "time": 1504867751580, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.482833, 38.504333, 10.56 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888431", "mag": 1.71, "time": 1504867332410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.491833, 38.504667, 9.32 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888421", "mag": 1.08, "time": 1504867024130, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.489, 38.504333, 8.33 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821868", "mag": 2.1, "time": 1504866678618, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -160.4655, 55.6664, 99.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821867", "mag": 1.4, "time": 1504866626331, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -147.0732, 60.0832, 7.7 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai08", "mag": 4.7, "time": 1504866065090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 125.9223, 5.4358, 106.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16778797", "mag": 1.0, "time": 1504865774499, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.3276, 61.5525, 10.3 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604189", "mag": 1.2, "time": 1504865677094, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -120.0784, 39.7853, 6.9 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888411", "mag": 1.53, "time": 1504865468770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.476167, 38.507167, 9.38 ] } }, +{ "type": "Feature", "properties": { "id": "hv61901161", "mag": 1.74, "time": 1504864814220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.466833, 19.2065, 36.007 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70234788", "mag": 2.39, "time": 1504864780960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.7805, 37.3255, 5.78 ] } }, +{ "type": "Feature", "properties": { "id": "ak16780611", "mag": 2.4, "time": 1504864612255, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.1592, 61.3969, 4.3 ] } }, +{ "type": "Feature", "properties": { "id": "ak16778631", "mag": 2.2, "time": 1504864578261, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -140.1624, 61.4081, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "uw61305087", "mag": 2.01, "time": 1504864189490, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.050833, 48.9275, 23.48 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821863", "mag": 1.7, "time": 1504863670078, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -178.4879, 51.7374, 21.1 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821862", "mag": 1.8, "time": 1504862106783, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.9215, 58.7206, 119.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahzn", "mag": 4.6, "time": 1504861954060, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4387, 15.3946, 52.08 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888396", "mag": 1.27, "time": 1504861876770, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8075, 37.512833, 1.14 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahzl", "mag": 4.5, "time": 1504861821720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4897, 15.3898, 66.84 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahzj", "mag": 4.5, "time": 1504861699670, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5329, 15.609, 39.64 ] } }, +{ "type": "Feature", "properties": { "id": "ci37757655", "mag": 1.16, "time": 1504861667220, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.622833, 33.107167, 12.71 ] } }, +{ "type": "Feature", "properties": { "id": "ak16778553", "mag": 1.9, "time": 1504861559880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.5627, 66.997, 11.1 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888391", "mag": 2.09, "time": 1504860900670, "felt": 0, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -123.456, 39.646667, 9.55 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay4f", "mag": 4.1, "time": 1504860843930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7484, 15.3716, 56.33 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888386", "mag": 2.1, "time": 1504860440750, "felt": 7, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.938, 37.831333, 7.32 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay4d", "mag": 4.4, "time": 1504860354710, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.834, 15.3232, 49.34 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arrb", "mag": 4.6, "time": 1504860180930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0811, 15.785, 52.87 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahzq", "mag": 4.5, "time": 1504860168930, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.9132, 15.2837, 68.08 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahz5", "mag": 5.3, "time": 1504859674330, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.1725, 15.2148, 50.77 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821859", "mag": 2.1, "time": 1504859557955, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -159.0839, 54.9712, 35.5 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604302", "mag": 1.1, "time": 1504859552745, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.4838, 37.3947, 8.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16778352", "mag": 1.2, "time": 1504859550711, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.4759, 63.0882, 87.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahz3", "mag": 4.3, "time": 1504859478950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.3904, 15.121, 30.23 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604182", "mag": 1.0, "time": 1504858881802, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.0405, 37.2978, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahz1", "mag": 4.3, "time": 1504858630350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.6852, 15.833, 76.27 ] } }, +{ "type": "Feature", "properties": { "id": "uu60239147", "mag": 2.45, "time": 1504858591000, "felt": 0, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.444167, 42.664333, 8.83 ] } }, +{ "type": "Feature", "properties": { "id": "us2000al72", "mag": 2.9, "time": 1504858190760, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -169.2139, 52.5352, 91.97 ] } }, +{ "type": "Feature", "properties": { "id": "uu60239137", "mag": 1.54, "time": 1504858110210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -110.647, 44.396167, 2.58 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arui", "mag": 4.2, "time": 1504858026090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4738, 14.8297, 45.65 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahyr", "mag": 4.3, "time": 1504857969210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -95.0003, 15.7457, 35.1 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arul", "mag": 4.3, "time": 1504857669250, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.801, 14.8524, 28.84 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahyk", "mag": 4.5, "time": 1504857596840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7758, 15.5339, 42.45 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604180", "mag": 1.2, "time": 1504857534482, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.0136, 37.3074, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821856", "mag": 1.2, "time": 1504857418267, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -157.4697, 58.6313, 13.4 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604280", "mag": 1.0, "time": 1504857267736, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -119.7805, 38.6696, 7.4 ] } }, +{ "type": "Feature", "properties": { "id": "us2000aruq", "mag": 4.3, "time": 1504857079940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.6759, 15.5537, 36.84 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahyf", "mag": 3.2, "time": 1504857069370, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4101, 42.5653, 6.35 ] } }, +{ "type": "Feature", "properties": { "id": "ci37757631", "mag": 1.01, "time": 1504856868740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -117.778, 36.031333, 2.15 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay0x", "mag": 4.1, "time": 1504856777400, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7738, 15.4661, 38.21 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821855", "mag": 1.3, "time": 1504856435979, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.538, 63.3273, 125.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahy9", "mag": 4.4, "time": 1504856316640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.6365, 15.5777, 47.53 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahy5", "mag": 3.2, "time": 1504855878650, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.446, 42.6598, 6.58 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahy6", "mag": 4.4, "time": 1504855839640, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7956, 15.6082, 34.65 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arrn", "mag": 4.1, "time": 1504855556590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2068, 15.1108, 51.65 ] } }, +{ "type": "Feature", "properties": { "id": "us2000al71", "mag": 3.0, "time": 1504855456090, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -164.0677, 53.8832, 50.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16778144", "mag": 3.2, "time": 1504855447301, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -135.611, 66.2631, 33.8 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arri", "mag": 4.2, "time": 1504855233030, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9743, 15.126, 35.68 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888356", "mag": 1.89, "time": 1504854775740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -121.3305, 41.068, 11.84 ] } }, +{ "type": "Feature", "properties": { "id": "mb80253029", "mag": 1.45, "time": 1504854704970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.500667, 45.881, 8.81 ] } }, +{ "type": "Feature", "properties": { "id": "ak16778123", "mag": 2.3, "time": 1504854630925, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -142.7701, 57.7458, 12.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888351", "mag": 1.26, "time": 1504854591960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.882167, 37.522833, -2.2 ] } }, +{ "type": "Feature", "properties": { "id": "hv61901091", "mag": 1.09, "time": 1504854245900, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.447167, 19.4775, 2.47 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay45", "mag": 4.2, "time": 1504854208800, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7971, 14.6019, 44.25 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahxm", "mag": 4.2, "time": 1504854069790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.8774, 14.8705, 34.98 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay43", "mag": 4.1, "time": 1504853757100, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.8976, 15.4459, 61.28 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahxh", "mag": 3.6, "time": 1504853614760, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -104.9507, 36.9956, 6.27 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821851", "mag": 1.1, "time": 1504853435000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.2544, 63.717, 83.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888336", "mag": 0.98, "time": 1504853065280, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.982833, 37.5425, 1.67 ] } }, +{ "type": "Feature", "properties": { "id": "ak16777966", "mag": 1.3, "time": 1504853023023, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -148.715, 63.9895, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arut", "mag": 4.2, "time": 1504852684440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2381, 15.5108, 43.98 ] } }, +{ "type": "Feature", "properties": { "id": "ci37757623", "mag": 0.96, "time": 1504852586240, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.789, 33.501333, 5.44 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arr6", "mag": 4.2, "time": 1504852477520, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.3508, 15.2654, 45.29 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888331", "mag": 1.19, "time": 1504852408190, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.736, 38.759167, 1.73 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arr7", "mag": 4.0, "time": 1504852398530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.7954, 14.8479, 70.92 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604169", "mag": 1.2, "time": 1504852379590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.2104, 36.4921, 0.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahxc", "mag": 4.7, "time": 1504852332790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 3.8455, 72.6309, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888321", "mag": 1.8, "time": 1504852052730, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.8065, 38.792167, 2.94 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahx3", "mag": 4.3, "time": 1504851979140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.627, 15.4476, 46.76 ] } }, +{ "type": "Feature", "properties": { "id": "ak16777937", "mag": 2.1, "time": 1504851258875, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.4392, 60.165, 78.3 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arr1", "mag": 4.3, "time": 1504851196580, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.9103, 15.3461, 69.88 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821848", "mag": 1.5, "time": 1504851158790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -152.7947, 60.1163, 106.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahwt", "mag": 4.6, "time": 1504850928420, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5535, 15.437, 48.5 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arr4", "mag": 4.3, "time": 1504850711370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.9041, 15.1749, 40.34 ] } }, +{ "type": "Feature", "properties": { "id": "ak16777931", "mag": 1.3, "time": 1504850655355, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -156.0257, 67.0569, 3.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arr2", "mag": 4.2, "time": 1504850627530, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -95.1989, 15.0884, 40.99 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arrk", "mag": 4.2, "time": 1504850557880, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7531, 15.4362, 36.4 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888301", "mag": 1.87, "time": 1504850251760, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.802333, 38.820667, 3.26 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahwk", "mag": 4.6, "time": 1504850223990, "felt": 0, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.1219, 15.2941, 54.75 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahx1", "mag": 4.3, "time": 1504850059440, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.9647, 15.304, 72.81 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay3u", "mag": 4.2, "time": 1504849825570, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.712, 15.4284, 47.14 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888296", "mag": 1.15, "time": 1504849761840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.800667, 38.847667, 0.54 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay3t", "mag": 4.4, "time": 1504849737970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.8795, 15.668, 47.2 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888271", "mag": 1.56, "time": 1504849628820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.8005, 38.846333, 0.64 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888266", "mag": 1.02, "time": 1504849513230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.801666, 38.847332, 0.61 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahw5", "mag": 5.0, "time": 1504849467850, "felt": 1, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.7228, 15.5333, 34.69 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arr3", "mag": 4.3, "time": 1504849426720, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0216, 15.4454, 53.87 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888261", "mag": 0.99, "time": 1504849348500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.761002, 38.832501, 0.49 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604165", "mag": 2.1, "time": 1504849234193, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -114.9828, 37.2854, 2.6 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arr0", "mag": 4.9, "time": 1504849156050, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.9438, 15.1471, 68.27 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay3s", "mag": 4.7, "time": 1504849019590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.8391, 15.6629, 60.73 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arux", "mag": 5.1, "time": 1504848867960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.0987, 14.9089, 42.35 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai3y", "mag": 2.5, "time": 1504848837100, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -98.4714, 36.5024, 6.91 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahvy", "mag": 5.2, "time": 1504848817820, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.4082, 15.2843, 45.81 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arqy", "mag": 4.6, "time": 1504848547140, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.9331, 15.1504, 39.51 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888241", "mag": 1.03, "time": 1504848340890, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.800835, 38.847832, 0.49 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahvs", "mag": 5.2, "time": 1504848276840, "felt": 3, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5946, 15.2029, 49.18 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888226", "mag": 1.48, "time": 1504848105550, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.802, 38.848167, 0.48 ] } }, +{ "type": "Feature", "properties": { "id": "nn00604164", "mag": 1.9, "time": 1504848096515, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -115.8669, 37.2911, 8.9 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ay3q", "mag": 4.8, "time": 1504848059390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.6096, 15.9617, 41.51 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahvc", "mag": 5.3, "time": 1504847863090, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.5672, 15.5726, 51.13 ] } }, +{ "type": "Feature", "properties": { "id": "nc71107624", "mag": 2.16, "time": 1504847827370, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.752167, 39.287167, 10.78 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888211", "mag": 1.01, "time": 1504847761210, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.765663, 38.848667, 6.01 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888201", "mag": 1.17, "time": 1504847709790, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.80883, 38.829666, 0.99 ] } }, +{ "type": "Feature", "properties": { "id": "pr2017251000", "mag": 3.73, "time": 1504847643290, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -68.2905, 19.3283, 52.0 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arqw", "mag": 4.8, "time": 1504847625230, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -93.8789, 15.4565, 61.03 ] } }, +{ "type": "Feature", "properties": { "id": "us2000arqv", "mag": 5.0, "time": 1504847479550, "felt": null, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ 128.5159, 2.4289, 235.24 ] } }, +{ "type": "Feature", "properties": { "id": "nc71107629", "mag": 1.35, "time": 1504847454920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.805833, 38.815333, 2.23 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888186", "mag": 1.45, "time": 1504847378350, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.766, 38.8255, 0.39 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888181", "mag": 2.28, "time": 1504847361610, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7555, 38.775667, 0.02 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888171", "mag": 1.83, "time": 1504847323920, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.7715, 38.817333, -0.11 ] } }, +{ "type": "Feature", "properties": { "id": "nc71107399", "mag": 1.12, "time": 1504847319000, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.771167, 38.819333, -0.31 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888156", "mag": 1.24, "time": 1504847297950, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.556, 38.807, 15.91 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888151", "mag": 1.36, "time": 1504847289840, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.806, 38.822, 1.41 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888176", "mag": 1.79, "time": 1504847279970, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.739667, 38.774, -0.49 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888146", "mag": 2.3, "time": 1504847258860, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.817833, 38.815167, 0.34 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888141", "mag": 2.42, "time": 1504847223340, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.800667, 38.83, 1.81 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahv7", "mag": 5.7, "time": 1504846893100, "felt": 26, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -94.2707, 15.1746, 35.87 ] } }, +{ "type": "Feature", "properties": { "id": "ak16777708", "mag": 1.1, "time": 1504846594461, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -151.0631, 61.4229, 6.8 ] } }, +{ "type": "Feature", "properties": { "id": "mb80252994", "mag": 1.72, "time": 1504846249390, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -112.541833, 46.857167, 12.55 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahv0", "mag": 8.1, "time": 1504846160000, "felt": 2494, "tsunami": 1 }, "geometry": { "type": "Point", "coordinates": [ -93.9067, 15.0356, 56.67 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ai6a", "mag": 2.5, "time": 1504846040410, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -163.4753, 53.7845, 22.98 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888131", "mag": 1.2, "time": 1504845594500, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.8105, 37.463833, -1.37 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821844", "mag": 2.0, "time": 1504845256450, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 178.621, 51.2706, 13.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci37757591", "mag": 1.24, "time": 1504844674340, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.899167, 34.321833, 9.91 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821842", "mag": 2.0, "time": 1504843966513, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ 179.0405, 51.3724, 44.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821841", "mag": 2.4, "time": 1504843627204, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -165.0538, 52.2197, 10.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821840", "mag": 1.4, "time": 1504843458180, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7807, 61.7731, 61.9 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821839", "mag": 1.1, "time": 1504843388032, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -149.5616, 61.4081, 45.5 ] } }, +{ "type": "Feature", "properties": { "id": "ak16777570", "mag": 1.9, "time": 1504843130740, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -173.812, 51.8664, 11.6 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821837", "mag": 1.7, "time": 1504843122073, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.717, 58.7435, 117.7 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821836", "mag": 1.3, "time": 1504842507708, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.7323, 60.5323, 52.2 ] } }, +{ "type": "Feature", "properties": { "id": "ci37757551", "mag": 1.47, "time": 1504841647940, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -116.7945, 33.496333, 3.33 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahus", "mag": 4.7, "time": 1504841042960, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -169.0592, 52.1619, 10.0 ] } }, +{ "type": "Feature", "properties": { "id": "ak16777419", "mag": 1.0, "time": 1504839731548, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -153.81, 64.7157, 15.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16777418", "mag": 2.4, "time": 1504839437977, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -174.7414, 52.1837, 13.2 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821832", "mag": 2.4, "time": 1504839217735, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -169.2407, 52.3318, 38.5 ] } }, +{ "type": "Feature", "properties": { "id": "hv61900746", "mag": 2.1, "time": 1504839173590, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -154.978833, 19.772, 43.163 ] } }, +{ "type": "Feature", "properties": { "id": "ismpkansas70234763", "mag": 1.85, "time": 1504838718270, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.887167, 37.203, 6.15 ] } }, +{ "type": "Feature", "properties": { "id": "ci37757519", "mag": 1.49, "time": 1504838267430, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -118.945167, 34.213667, 19.49 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahub", "mag": 4.3, "time": 1504837583700, "felt": 823, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -97.683, 36.6996, 6.073 ] } }, +{ "type": "Feature", "properties": { "id": "ak16777416", "mag": 1.3, "time": 1504836895690, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -150.6982, 63.5777, 11.7 ] } }, +{ "type": "Feature", "properties": { "id": "uw61304877", "mag": 1.15, "time": 1504836765080, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.568333, 48.699167, 3.29 ] } }, +{ "type": "Feature", "properties": { "id": "us2000ahu8", "mag": 3.7, "time": 1504836433340, "felt": 2, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -111.4569, 42.6238, 5.0 ] } }, +{ "type": "Feature", "properties": { "id": "nc72888096", "mag": 2.03, "time": 1504835142230, "felt": 4, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -122.053667, 37.835167, 7.59 ] } }, +{ "type": "Feature", "properties": { "id": "ak16821829", "mag": 1.5, "time": 1504834613166, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -163.7652, 67.5597, 6.1 ] } }, +{ "type": "Feature", "properties": { "id": "hv61900626", "mag": 2.91, "time": 1504833891990, "felt": null, "tsunami": 0 }, "geometry": { "type": "Point", "coordinates": [ -155.011833, 19.399333, 2.609 ] } } +] +} diff --git a/examples/data/hunan-citys.json b/examples/data/hunan-citys.json new file mode 100644 index 00000000000..2e444b298af --- /dev/null +++ b/examples/data/hunan-citys.json @@ -0,0 +1 @@ +{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"adcode":430100,"name":"长沙市","center":[112.982279,28.19409],"centroid":[113.158697,28.224232],"childrenNum":9,"level":"city","parent":{"adcode":430000},"subFeatureIndex":0,"acroutes":[100000,430000]},"geometry":{"type":"MultiPolygon","coordinates":[[[[111.902613,28.021982],[111.896377,28.00871],[111.908303,28.000189],[111.900097,27.981343],[111.912624,27.973803],[111.926848,27.980851],[111.936311,27.991231],[111.951246,27.987079],[111.964156,27.965171],[111.982264,27.954351],[111.99025,27.940962],[111.999714,27.907837],[112.017548,27.906307],[112.030513,27.914398],[112.04408,27.912156],[112.051246,27.919208],[112.060218,27.920028],[112.087734,27.908384],[112.093095,27.895919],[112.101137,27.893622],[112.11826,27.897614],[112.127669,27.911227],[112.137625,27.905705],[112.149551,27.908001],[112.160656,27.916912],[112.158851,27.928337],[112.173457,27.940743],[112.180897,27.93812],[112.18303,27.947083],[112.199223,27.969487],[112.199059,27.96222],[112.211094,27.95375],[112.223785,27.971399],[112.23035,27.961837],[112.245284,27.963695],[112.257647,27.95916],[112.298457,27.971235],[112.306663,27.971618],[112.313009,27.95916],[112.328217,27.963968],[112.342604,27.957193],[112.354037,27.965662],[112.371105,27.970033],[112.382757,27.967957],[112.389814,27.962111],[112.402341,27.966373],[112.411313,27.963258],[112.415361,27.99216],[112.398129,27.996857],[112.407101,28.001118],[112.415033,28.01521],[112.41011,28.031593],[112.413282,28.040657],[112.42291,28.049339],[112.443972,28.05731],[112.459125,28.051905],[112.468698,28.058893],[112.480241,28.056272],[112.486259,28.04022],[112.516401,28.018814],[112.508086,28.008874],[112.511806,27.994672],[112.531117,27.994126],[112.539486,27.975388],[112.553874,27.972601],[112.561368,27.980469],[112.574279,27.967848],[112.576686,27.959324],[112.596926,27.953477],[112.594738,27.931507],[112.599005,27.921176],[112.606937,27.918006],[112.611642,27.900293],[112.619684,27.899801],[112.630515,27.890561],[112.633852,27.880116],[112.649443,27.880281],[112.657047,27.900347],[112.651248,27.918552],[112.641948,27.923308],[112.654585,27.941509],[112.687135,27.927079],[112.683415,27.920301],[112.706062,27.923089],[112.712463,27.916475],[112.731008,27.916967],[112.731828,27.929156],[112.743098,27.931944],[112.744082,27.946427],[112.758415,27.965389],[112.764487,27.986806],[112.763667,28.00232],[112.770122,28.017449],[112.779476,28.02149],[112.772419,28.031047],[112.777015,28.036944],[112.790472,28.031757],[112.792441,28.023729],[112.804257,28.025641],[112.808689,28.03689],[112.791785,28.049775],[112.78254,28.052778],[112.777124,28.061131],[112.782704,28.073577],[112.802124,28.069374],[112.81859,28.06921],[112.81591,28.061513],[112.825538,28.043988],[112.833525,28.037709],[112.831774,28.027388],[112.838776,28.021436],[112.850483,28.021272],[112.859728,28.004177],[112.858689,27.988882],[112.873021,27.990302],[112.869903,28.001937],[112.877562,28.004231],[112.882266,27.992924],[112.893481,27.99216],[112.883744,27.979158],[112.885658,27.974295],[112.900264,27.97812],[112.906555,27.971072],[112.914542,27.977737],[112.924116,27.974896],[112.928328,27.983583],[112.941402,27.984839],[112.937628,27.992378],[112.928054,27.993088],[112.935822,28.003958],[112.93347,28.015264],[112.945724,28.014773],[112.956774,27.998933],[112.992059,27.975825],[113.003164,27.965171],[113.023897,27.976972],[113.022858,27.985276],[113.035932,27.977409],[113.030079,27.991941],[113.041676,28.006198],[113.071709,28.010895],[113.090965,27.989865],[113.073733,27.972],[113.082322,27.964296],[113.09009,27.965171],[113.086698,27.950089],[113.101797,27.933693],[113.108635,27.933037],[113.122092,27.914288],[113.136644,27.914999],[113.138996,27.927845],[113.132978,27.930578],[113.131064,27.942219],[113.138832,27.945717],[113.135495,27.953422],[113.146545,27.953859],[113.158744,27.966373],[113.149554,27.980851],[113.148624,27.992269],[113.17067,27.999916],[113.164106,28.006744],[113.175812,28.015046],[113.190801,28.010676],[113.209182,28.012315],[113.214598,28.024057],[113.226578,28.020398],[113.228165,28.014445],[113.243865,28.009912],[113.250266,28.019688],[113.259839,28.013243],[113.258252,27.996475],[113.264051,28.011714],[113.271436,27.99063],[113.269576,27.977027],[113.277673,27.970634],[113.271819,27.961783],[113.271546,27.949706],[113.261863,27.948559],[113.259073,27.941782],[113.266677,27.934185],[113.273296,27.91888],[113.287574,27.916858],[113.2902,27.909915],[113.274883,27.909587],[113.281611,27.894443],[113.28101,27.880882],[113.274992,27.862671],[113.2902,27.865843],[113.288504,27.877218],[113.300102,27.877218],[113.300758,27.868851],[113.315747,27.865077],[113.331338,27.856928],[113.343045,27.858569],[113.359402,27.848067],[113.384402,27.854357],[113.399993,27.853373],[113.413231,27.857803],[113.416185,27.872789],[113.415529,27.888975],[113.424172,27.897668],[113.446163,27.895645],[113.459511,27.900183],[113.458144,27.908056],[113.463614,27.918224],[113.481557,27.927134],[113.490201,27.939432],[113.507323,27.938175],[113.521547,27.942328],[113.525923,27.959925],[113.554205,27.961236],[113.567717,27.964788],[113.575704,27.959761],[113.578221,27.93976],[113.569413,27.92779],[113.571383,27.912594],[113.576798,27.899746],[113.591405,27.891271],[113.597258,27.902917],[113.594796,27.910352],[113.602181,27.913578],[113.633965,27.895755],[113.644906,27.879734],[113.654971,27.87782],[113.660661,27.884929],[113.672203,27.876835],[113.69693,27.86989],[113.72286,27.885749],[113.730409,27.88471],[113.7367,27.90576],[113.745016,27.915983],[113.75344,27.934677],[113.771055,27.952712],[113.792718,27.955062],[113.793101,27.96222],[113.802948,27.974022],[113.82193,27.982272],[113.826799,27.973257],[113.845235,27.971673],[113.852018,27.976098],[113.852182,27.988609],[113.859841,28.001719],[113.869524,28.004231],[113.878714,27.991941],[113.900158,27.987571],[113.914272,27.99134],[113.935552,28.018923],[113.944032,28.014172],[113.965585,28.016848],[113.956997,28.028426],[113.957927,28.034815],[113.968813,28.041149],[113.989272,28.038746],[114.000596,28.040439],[114.026855,28.031811],[114.027566,28.041804],[114.047095,28.057473],[114.036318,28.078162],[114.019086,28.085422],[114.02855,28.084767],[114.027019,28.092408],[114.017336,28.102777],[114.013452,28.124003],[114.007216,28.125421],[114.005957,28.144842],[113.999885,28.147243],[113.992664,28.161424],[114.00738,28.166551],[114.012358,28.175113],[114.025049,28.172168],[114.048025,28.176694],[114.053441,28.171077],[114.068649,28.171677],[114.083802,28.179203],[114.105301,28.181493],[114.106614,28.201613],[114.12122,28.213116],[114.129645,28.228161],[114.143759,28.238135],[114.145017,28.247782],[114.170673,28.253504],[114.18052,28.249798],[114.184678,28.267617],[114.19912,28.272466],[114.198135,28.290717],[114.215695,28.293985],[114.235116,28.310925],[114.250652,28.318223],[114.255521,28.326609],[114.247096,28.338099],[114.260116,28.355685],[114.250597,28.368097],[114.258092,28.372942],[114.256013,28.3921],[114.252457,28.395747],[114.228168,28.39542],[114.214601,28.403039],[114.202238,28.424422],[114.193376,28.430842],[114.172369,28.432801],[114.182982,28.436881],[114.219306,28.470549],[114.218814,28.482621],[114.195619,28.498552],[114.174667,28.497356],[114.154645,28.507577],[114.14064,28.523395],[114.138124,28.533722],[114.12319,28.534755],[114.118485,28.538994],[114.100651,28.540299],[114.086756,28.555895],[114.073901,28.555188],[114.065968,28.547689],[114.051745,28.544374],[114.040038,28.551004],[114.025432,28.542798],[114.015038,28.545679],[114.013561,28.554591],[113.995782,28.564915],[113.975979,28.564752],[113.962467,28.542309],[113.950979,28.53644],[113.941242,28.526385],[113.935443,28.531385],[113.917883,28.525461],[113.903222,28.528613],[113.889546,28.515622],[113.876471,28.518884],[113.858473,28.532255],[113.844414,28.523885],[113.832434,28.498878],[113.832981,28.489037],[113.824885,28.484089],[113.817554,28.466851],[113.806394,28.458638],[113.78495,28.457551],[113.7739,28.451024],[113.7617,28.451405],[113.729698,28.441287],[113.717773,28.424042],[113.704643,28.422192],[113.676963,28.442049],[113.657324,28.447706],[113.661427,28.45445],[113.64972,28.470005],[113.635825,28.482621],[113.615311,28.495725],[113.598133,28.51198],[113.575923,28.536386],[113.558035,28.533179],[113.547258,28.52508],[113.52822,28.528287],[113.51542,28.537038],[113.507378,28.536929],[113.500923,28.559155],[113.491349,28.570457],[113.474391,28.579801],[113.462739,28.596532],[113.454369,28.591046],[113.446492,28.593925],[113.430408,28.590286],[113.424336,28.578715],[113.414599,28.590883],[113.42078,28.609513],[113.4245,28.636068],[113.411809,28.632267],[113.384785,28.644538],[113.375813,28.643343],[113.360113,28.631453],[113.358581,28.622384],[113.349226,28.616573],[113.332213,28.618963],[113.320342,28.615759],[113.316513,28.628629],[113.310003,28.633136],[113.283635,28.638728],[113.27253,28.631398],[113.258854,28.627597],[113.251797,28.629715],[113.245944,28.640629],[113.243592,28.656156],[113.233635,28.661639],[113.234729,28.646438],[113.216458,28.638077],[113.212957,28.632647],[113.215473,28.620809],[113.195014,28.603648],[113.183252,28.596858],[113.189653,28.580181],[113.186097,28.567957],[113.194685,28.56649],[113.200758,28.555569],[113.19392,28.55008],[113.19474,28.541549],[113.185933,28.529211],[113.183088,28.510132],[113.18544,28.503391],[113.171381,28.492408],[113.169904,28.480446],[113.154313,28.470875],[113.128657,28.473975],[113.132103,28.490777],[113.130462,28.498498],[113.111917,28.499313],[113.0966,28.50812],[113.085002,28.508229],[113.07904,28.521873],[113.067935,28.519264],[113.063722,28.505294],[113.041403,28.484905],[113.027781,28.483219],[113.019028,28.47305],[112.99184,28.460923],[112.974006,28.465274],[112.960768,28.477075],[112.977726,28.498552],[112.974882,28.506979],[112.978656,28.52345],[112.965637,28.521167],[112.939816,28.508501],[112.921271,28.520297],[112.898733,28.517525],[112.891293,28.524754],[112.87149,28.519156],[112.872365,28.500618],[112.852617,28.512524],[112.845341,28.510621],[112.822529,28.512796],[112.822419,28.528396],[112.815581,28.527798],[112.808579,28.519319],[112.792058,28.523015],[112.788831,28.535027],[112.808798,28.559046],[112.796435,28.558503],[112.772693,28.546385],[112.757704,28.529755],[112.753874,28.518014],[112.746872,28.510458],[112.731664,28.507414],[112.714542,28.510621],[112.700428,28.519699],[112.685384,28.525407],[112.672583,28.517525],[112.663229,28.501053],[112.651741,28.495671],[112.654421,28.484524],[112.639815,28.469352],[112.627288,28.468265],[112.624279,28.446074],[112.612134,28.424531],[112.594793,28.414629],[112.594355,28.40761],[112.584235,28.40244],[112.578436,28.382358],[112.580351,28.372887],[112.575427,28.369077],[112.575209,28.354596],[112.562462,28.344742],[112.564432,28.333144],[112.571379,28.324976],[112.560493,28.325411],[112.553928,28.318931],[112.535766,28.325466],[112.534563,28.332],[112.525974,28.325956],[112.505296,28.320728],[112.500974,28.311905],[112.486915,28.309236],[112.472965,28.317733],[112.466018,28.312886],[112.451248,28.317842],[112.438337,28.310652],[112.432976,28.317896],[112.429311,28.311143],[112.420066,28.312559],[112.422692,28.305587],[112.408468,28.294366],[112.404803,28.29867],[112.393753,28.290281],[112.377998,28.290063],[112.370339,28.284397],[112.352779,28.291261],[112.345284,28.289518],[112.349168,28.281837],[112.358632,28.283471],[112.356937,28.277369],[112.346761,28.274809],[112.332921,28.284397],[112.316674,28.282981],[112.322473,28.263258],[112.306444,28.261351],[112.294135,28.247073],[112.288282,28.254049],[112.280678,28.252632],[112.264431,28.235683],[112.255733,28.233448],[112.251685,28.2244],[112.237954,28.210445],[112.227286,28.221239],[112.223293,28.233939],[112.210109,28.239225],[112.195503,28.23323],[112.177997,28.235737],[112.169518,28.245602],[112.146214,28.254539],[112.137297,28.266636],[112.123128,28.266146],[112.11629,28.271703],[112.099058,28.270069],[112.093424,28.265001],[112.082264,28.267889],[112.080677,28.260806],[112.051684,28.25127],[112.033139,28.252468],[112.009671,28.244021],[112.003981,28.235029],[112.003489,28.224509],[111.986585,28.224182],[111.962132,28.208864],[111.961147,28.198124],[111.944736,28.186728],[111.941782,28.172277],[111.933248,28.168132],[111.93188,28.133332],[111.90885,28.116036],[111.899167,28.09983],[111.91525,28.082802],[111.914101,28.079363],[111.926246,28.065498],[111.911038,28.052287],[111.907537,28.041804],[111.913117,28.027989],[111.902613,28.021982]]]]}},{"type":"Feature","properties":{"adcode":430200,"name":"株洲市","center":[113.151737,27.835806],"centroid":[113.522078,27.11883],"childrenNum":9,"level":"city","parent":{"adcode":430000},"subFeatureIndex":1,"acroutes":[100000,430000]},"geometry":{"type":"MultiPolygon","coordinates":[[[[113.730409,27.88471],[113.72286,27.885749],[113.69693,27.86989],[113.672203,27.876835],[113.660661,27.884929],[113.654971,27.87782],[113.644906,27.879734],[113.633965,27.895755],[113.602181,27.913578],[113.594796,27.910352],[113.597258,27.902917],[113.591405,27.891271],[113.576798,27.899746],[113.571383,27.912594],[113.569413,27.92779],[113.578221,27.93976],[113.575704,27.959761],[113.567717,27.964788],[113.554205,27.961236],[113.525923,27.959925],[113.521547,27.942328],[113.507323,27.938175],[113.490201,27.939432],[113.481557,27.927134],[113.463614,27.918224],[113.458144,27.908056],[113.459511,27.900183],[113.446163,27.895645],[113.424172,27.897668],[113.415529,27.888975],[113.416185,27.872789],[113.413231,27.857803],[113.399993,27.853373],[113.384402,27.854357],[113.359402,27.848067],[113.343045,27.858569],[113.331338,27.856928],[113.315747,27.865077],[113.300758,27.868851],[113.300102,27.877218],[113.288504,27.877218],[113.2902,27.865843],[113.274992,27.862671],[113.28101,27.880882],[113.281611,27.894443],[113.274883,27.909587],[113.2902,27.909915],[113.287574,27.916858],[113.273296,27.91888],[113.266677,27.934185],[113.259073,27.941782],[113.261863,27.948559],[113.271546,27.949706],[113.271819,27.961783],[113.277673,27.970634],[113.269576,27.977027],[113.271436,27.99063],[113.264051,28.011714],[113.258252,27.996475],[113.259839,28.013243],[113.250266,28.019688],[113.243865,28.009912],[113.228165,28.014445],[113.226578,28.020398],[113.214598,28.024057],[113.209182,28.012315],[113.190801,28.010676],[113.175812,28.015046],[113.164106,28.006744],[113.17067,27.999916],[113.148624,27.992269],[113.149554,27.980851],[113.158744,27.966373],[113.146545,27.953859],[113.135495,27.953422],[113.138832,27.945717],[113.131064,27.942219],[113.132978,27.930578],[113.138996,27.927845],[113.136644,27.914999],[113.122092,27.914288],[113.108635,27.933037],[113.101797,27.933693],[113.086698,27.950089],[113.069193,27.938557],[113.061315,27.910899],[113.048405,27.890998],[113.045943,27.875632],[113.038613,27.864093],[113.046381,27.846426],[113.03812,27.843308],[113.012464,27.822902],[113.002343,27.810427],[113.003766,27.798772],[113.023022,27.791821],[113.033689,27.77064],[113.034893,27.762812],[113.029532,27.752082],[113.032048,27.742391],[113.053711,27.733356],[113.058963,27.727114],[113.050429,27.711013],[113.026195,27.711013],[113.00847,27.684775],[112.995068,27.676613],[112.994575,27.665819],[113.003985,27.652395],[113.016129,27.660395],[113.027289,27.659025],[113.031446,27.651901],[113.024554,27.642585],[113.03905,27.630747],[113.038832,27.621594],[113.018974,27.612714],[113.007759,27.621649],[112.997147,27.616112],[112.999006,27.606135],[113.009017,27.598734],[112.988831,27.578337],[112.972146,27.568796],[112.970779,27.561666],[112.976523,27.54214],[112.975265,27.526287],[112.969411,27.511638],[112.975757,27.501267],[112.987573,27.498688],[112.983963,27.487328],[112.971381,27.475199],[112.979039,27.467515],[112.985659,27.469765],[112.989105,27.447094],[112.995396,27.438309],[112.999225,27.435619],[112.994247,27.407064],[113.002015,27.392729],[113.024171,27.385807],[113.021545,27.378337],[113.025265,27.367239],[113.042223,27.350921],[113.033306,27.345041],[113.032541,27.329269],[113.048843,27.320915],[113.04381,27.309647],[113.051031,27.287492],[113.068427,27.280949],[113.085878,27.266433],[113.082431,27.253895],[113.092606,27.238274],[113.087847,27.235469],[113.107814,27.225238],[113.115473,27.205597],[113.127508,27.207358],[113.133252,27.229638],[113.144138,27.249275],[113.148296,27.251695],[113.164324,27.236019],[113.173734,27.233489],[113.182979,27.240915],[113.23183,27.237339],[113.248406,27.23943],[113.255408,27.223642],[113.271929,27.205707],[113.283964,27.178634],[113.280298,27.166636],[113.260058,27.173186],[113.257815,27.160141],[113.245944,27.151609],[113.244795,27.139994],[113.236042,27.145224],[113.219467,27.131736],[113.196053,27.14181],[113.193482,27.1357],[113.16799,27.126175],[113.164543,27.101285],[113.170779,27.099027],[113.175101,27.088838],[113.193865,27.076059],[113.199171,27.056888],[113.198022,27.04069],[113.215856,27.0408],[113.220014,27.024434],[113.23462,27.021403],[113.235714,27.014789],[113.224937,27.012474],[113.21892,27.002939],[113.226852,26.994671],[113.221546,26.974549],[113.225594,26.956298],[113.235331,26.951721],[113.245014,26.93832],[113.280955,26.939974],[113.278329,26.928447],[113.266458,26.918408],[113.257104,26.917691],[113.254751,26.900259],[113.239708,26.894466],[113.24288,26.889279],[113.239106,26.877747],[113.227125,26.876423],[113.232869,26.860971],[113.252399,26.839224],[113.259784,26.827797],[113.280627,26.825202],[113.273789,26.813056],[113.285331,26.799694],[113.285441,26.79003],[113.27811,26.777715],[113.283417,26.771473],[113.299281,26.768104],[113.306283,26.773517],[113.315091,26.79616],[113.326305,26.80759],[113.338121,26.81024],[113.363669,26.800081],[113.384456,26.797099],[113.394303,26.804774],[113.404697,26.797596],[113.412684,26.782575],[113.428111,26.769761],[113.427618,26.764569],[113.413286,26.72982],[113.400758,26.706943],[113.382049,26.69915],[113.381448,26.6939],[113.392224,26.674885],[113.399883,26.666593],[113.400977,26.658245],[113.415474,26.645694],[113.418045,26.629381],[113.411371,26.610134],[113.400266,26.605211],[113.399117,26.596969],[113.414599,26.587399],[113.429478,26.558738],[113.458144,26.561782],[113.467279,26.559347],[113.477072,26.562667],[113.491021,26.575338],[113.495781,26.58419],[113.509183,26.59271],[113.523461,26.595476],[113.541295,26.59271],[113.554971,26.585352],[113.562192,26.575172],[113.558691,26.549497],[113.572969,26.519111],[113.587028,26.520882],[113.589162,26.511416],[113.603604,26.507652],[113.595671,26.479913],[113.588998,26.467121],[113.603275,26.448345],[113.609621,26.431007],[113.607707,26.419096],[113.583199,26.394661],[113.583527,26.370331],[113.592499,26.360187],[113.597149,26.34583],[113.598954,26.326646],[113.60705,26.315113],[113.617061,26.308236],[113.615201,26.278896],[113.64414,26.267968],[113.655464,26.270575],[113.671602,26.256761],[113.67833,26.247273],[113.708473,26.234067],[113.725158,26.223745],[113.738724,26.18317],[113.736536,26.159351],[113.729261,26.139248],[113.72204,26.133139],[113.702455,26.124419],[113.693265,26.09581],[113.709074,26.065805],[113.736427,26.041129],[113.750705,26.041629],[113.761536,26.04791],[113.780957,26.066139],[113.780792,26.093699],[113.791624,26.10431],[113.805793,26.100033],[113.811099,26.086421],[113.824775,26.084087],[113.845071,26.095699],[113.849611,26.107588],[113.860278,26.119309],[113.888451,26.130362],[113.896438,26.135527],[113.902839,26.148023],[113.914491,26.15874],[113.916953,26.171344],[113.930246,26.172788],[113.94611,26.184502],[113.949502,26.192663],[113.970071,26.202099],[113.971548,26.219305],[113.980191,26.226464],[113.978933,26.23773],[113.989108,26.246663],[114.00273,26.251324],[114.011264,26.258481],[114.029316,26.266359],[114.02122,26.283056],[114.02576,26.296812],[114.041789,26.309567],[114.035607,26.323375],[114.047588,26.337403],[114.039765,26.345663],[114.039655,26.361407],[114.030574,26.376594],[114.036264,26.377314],[114.042992,26.390227],[114.049885,26.391114],[114.062522,26.406131],[114.071658,26.409843],[114.076472,26.404136],[114.085443,26.406242],[114.089054,26.418043],[114.085772,26.422808],[114.086428,26.439593],[114.090531,26.455712],[114.110115,26.483014],[114.09808,26.484121],[114.086756,26.478196],[114.072697,26.479913],[114.084185,26.504994],[114.086264,26.525753],[114.097533,26.541196],[114.096275,26.548279],[114.105903,26.559679],[114.108091,26.575006],[114.084677,26.577772],[114.069634,26.575836],[114.060881,26.580649],[114.042555,26.57993],[114.033091,26.585629],[114.019743,26.587454],[114.017664,26.599624],[113.996384,26.61561],[113.984404,26.614559],[113.960005,26.618099],[113.953167,26.613729],[113.938944,26.612844],[113.906449,26.615665],[113.901362,26.627888],[113.88495,26.635796],[113.881449,26.654319],[113.867992,26.652992],[113.860497,26.664105],[113.862686,26.689478],[113.861373,26.705948],[113.856449,26.714735],[113.856777,26.735622],[113.852839,26.750041],[113.85355,26.76943],[113.845946,26.788153],[113.836755,26.79616],[113.835771,26.806375],[113.857926,26.826803],[113.85902,26.833814],[113.877456,26.859481],[113.892062,26.860529],[113.891406,26.897831],[113.903058,26.91063],[113.902182,26.925855],[113.926362,26.947144],[113.921384,26.960047],[113.8925,26.964734],[113.879808,26.983315],[113.871493,26.990095],[113.870727,27.003876],[113.863287,27.018482],[113.848134,27.016663],[113.845563,27.028402],[113.838506,27.034959],[113.8239,27.036116],[113.816679,27.046806],[113.811919,27.081568],[113.807652,27.097705],[113.803276,27.099358],[113.788178,27.086525],[113.779972,27.087131],[113.77193,27.096384],[113.774173,27.120283],[113.77937,27.137186],[113.801088,27.158435],[113.814709,27.174286],[113.823025,27.192997],[113.847204,27.222487],[113.853057,27.234754],[113.859896,27.269127],[113.871712,27.284743],[113.869141,27.296509],[113.858364,27.298763],[113.854644,27.305249],[113.872915,27.346745],[113.876198,27.382072],[113.872642,27.384874],[113.837412,27.371909],[113.822915,27.364767],[113.81088,27.368393],[113.783254,27.362185],[113.762904,27.360866],[113.743648,27.348723],[113.722751,27.348998],[113.717991,27.342403],[113.699775,27.332072],[113.672149,27.333281],[113.657707,27.347459],[113.639162,27.349932],[113.625923,27.343228],[113.616678,27.345426],[113.60437,27.365536],[113.602674,27.385753],[113.618866,27.398441],[113.629753,27.401022],[113.620672,27.418267],[113.606886,27.417498],[113.59775,27.428755],[113.599665,27.450333],[113.592006,27.468173],[113.614381,27.477449],[113.613724,27.48409],[113.627017,27.498029],[113.622367,27.503627],[113.628604,27.512241],[113.621875,27.52678],[113.610442,27.514546],[113.583363,27.524696],[113.578822,27.545157],[113.599391,27.567425],[113.601525,27.57905],[113.608801,27.584972],[113.604917,27.594622],[113.607269,27.625376],[113.619413,27.641763],[113.652127,27.663628],[113.659238,27.672011],[113.669742,27.694855],[113.696328,27.718899],[113.700431,27.731002],[113.699009,27.741131],[113.73123,27.774471],[113.763232,27.799319],[113.767226,27.808184],[113.767062,27.824489],[113.763506,27.842214],[113.756339,27.86021],[113.731503,27.869125],[113.730409,27.88471]]]]}},{"type":"Feature","properties":{"adcode":430300,"name":"湘潭市","center":[112.944052,27.82973],"centroid":[112.608495,27.72863],"childrenNum":5,"level":"city","parent":{"adcode":430000},"subFeatureIndex":2,"acroutes":[100000,430000]},"geometry":{"type":"MultiPolygon","coordinates":[[[[111.999714,27.907837],[112.012296,27.87864],[112.014813,27.847083],[112.026957,27.835157],[112.040524,27.839534],[112.04687,27.817048],[112.069901,27.80397],[112.087023,27.81382],[112.101246,27.807363],[112.106498,27.790617],[112.097745,27.776551],[112.098675,27.765001],[112.11268,27.761991],[112.130623,27.747428],[112.110929,27.738722],[112.106389,27.717147],[112.100699,27.722295],[112.099113,27.73467],[112.087187,27.733739],[112.081826,27.721747],[112.092111,27.716325],[112.083303,27.71523],[112.071761,27.720652],[112.053489,27.714135],[112.045338,27.706303],[112.052997,27.690527],[112.048785,27.688336],[112.048183,27.674038],[112.05803,27.680393],[112.07094,27.6696],[112.067001,27.658477],[112.078052,27.645764],[112.091235,27.642366],[112.104255,27.653381],[112.113664,27.653436],[112.11722,27.645435],[112.124879,27.646147],[112.134616,27.654696],[112.137953,27.666258],[112.145776,27.665162],[112.154857,27.64949],[112.166673,27.660066],[112.176083,27.650203],[112.199387,27.654313],[112.206827,27.651627],[112.2071,27.670531],[112.216564,27.675846],[112.222636,27.671517],[112.230623,27.685871],[112.240853,27.691075],[112.243369,27.707727],[112.268534,27.700935],[112.290525,27.7057],[112.304201,27.697868],[112.315744,27.685871],[112.320613,27.675298],[112.315142,27.664285],[112.313501,27.651025],[112.288884,27.646915],[112.281882,27.643298],[112.283906,27.633652],[112.298019,27.620991],[112.330788,27.602517],[112.334289,27.581408],[112.332429,27.569947],[112.325317,27.556182],[112.308578,27.53457],[112.301411,27.503188],[112.306389,27.492816],[112.321652,27.496493],[112.328709,27.490511],[112.333851,27.495725],[112.346105,27.496273],[112.348129,27.488206],[112.365799,27.480907],[112.373731,27.48656],[112.393479,27.492542],[112.391948,27.499731],[112.401193,27.503736],[112.399606,27.510266],[112.406007,27.524092],[112.417604,27.527713],[112.427123,27.526067],[112.435985,27.514546],[112.429639,27.499785],[112.446379,27.491499],[112.460164,27.490456],[112.47023,27.461916],[112.480952,27.453132],[112.500974,27.445831],[112.521981,27.429194],[112.531007,27.430293],[112.538885,27.416674],[112.55453,27.424911],[112.553327,27.432379],[112.566893,27.441768],[112.576576,27.434466],[112.587244,27.437046],[112.592605,27.454999],[112.608305,27.455987],[112.615143,27.465978],[112.63046,27.466252],[112.639596,27.45983],[112.64627,27.464715],[112.659727,27.452309],[112.673075,27.456811],[112.69069,27.454121],[112.687244,27.437101],[112.678491,27.42892],[112.677397,27.419255],[112.685658,27.405691],[112.704093,27.407668],[112.715308,27.404263],[112.727507,27.394871],[112.735822,27.401517],[112.748404,27.39899],[112.76033,27.403988],[112.771818,27.392784],[112.77417,27.376359],[112.791566,27.36213],[112.80382,27.36202],[112.806282,27.348723],[112.799826,27.344327],[112.807868,27.338392],[112.815691,27.343777],[112.831118,27.338337],[112.834947,27.354382],[112.852999,27.355097],[112.863886,27.351196],[112.869958,27.356141],[112.901906,27.360536],[112.920177,27.356635],[112.924936,27.367074],[112.921818,27.409865],[112.9251,27.418871],[112.939597,27.426284],[112.955954,27.430293],[112.978109,27.439188],[112.995396,27.438309],[112.989105,27.447094],[112.985659,27.469765],[112.979039,27.467515],[112.971381,27.475199],[112.983963,27.487328],[112.987573,27.498688],[112.975757,27.501267],[112.969411,27.511638],[112.975265,27.526287],[112.976523,27.54214],[112.970779,27.561666],[112.972146,27.568796],[112.988831,27.578337],[113.009017,27.598734],[112.999006,27.606135],[112.997147,27.616112],[113.007759,27.621649],[113.018974,27.612714],[113.038832,27.621594],[113.03905,27.630747],[113.024554,27.642585],[113.031446,27.651901],[113.027289,27.659025],[113.016129,27.660395],[113.003985,27.652395],[112.994575,27.665819],[112.995068,27.676613],[113.00847,27.684775],[113.026195,27.711013],[113.050429,27.711013],[113.058963,27.727114],[113.053711,27.733356],[113.032048,27.742391],[113.029532,27.752082],[113.034893,27.762812],[113.033689,27.77064],[113.023022,27.791821],[113.003766,27.798772],[113.002343,27.810427],[113.012464,27.822902],[113.03812,27.843308],[113.046381,27.846426],[113.038613,27.864093],[113.045943,27.875632],[113.048405,27.890998],[113.061315,27.910899],[113.069193,27.938557],[113.086698,27.950089],[113.09009,27.965171],[113.082322,27.964296],[113.073733,27.972],[113.090965,27.989865],[113.071709,28.010895],[113.041676,28.006198],[113.030079,27.991941],[113.035932,27.977409],[113.022858,27.985276],[113.023897,27.976972],[113.003164,27.965171],[112.992059,27.975825],[112.956774,27.998933],[112.945724,28.014773],[112.93347,28.015264],[112.935822,28.003958],[112.928054,27.993088],[112.937628,27.992378],[112.941402,27.984839],[112.928328,27.983583],[112.924116,27.974896],[112.914542,27.977737],[112.906555,27.971072],[112.900264,27.97812],[112.885658,27.974295],[112.883744,27.979158],[112.893481,27.99216],[112.882266,27.992924],[112.877562,28.004231],[112.869903,28.001937],[112.873021,27.990302],[112.858689,27.988882],[112.859728,28.004177],[112.850483,28.021272],[112.838776,28.021436],[112.831774,28.027388],[112.833525,28.037709],[112.825538,28.043988],[112.81591,28.061513],[112.81859,28.06921],[112.802124,28.069374],[112.782704,28.073577],[112.777124,28.061131],[112.78254,28.052778],[112.791785,28.049775],[112.808689,28.03689],[112.804257,28.025641],[112.792441,28.023729],[112.790472,28.031757],[112.777015,28.036944],[112.772419,28.031047],[112.779476,28.02149],[112.770122,28.017449],[112.763667,28.00232],[112.764487,27.986806],[112.758415,27.965389],[112.744082,27.946427],[112.743098,27.931944],[112.731828,27.929156],[112.731008,27.916967],[112.712463,27.916475],[112.706062,27.923089],[112.683415,27.920301],[112.687135,27.927079],[112.654585,27.941509],[112.641948,27.923308],[112.651248,27.918552],[112.657047,27.900347],[112.649443,27.880281],[112.633852,27.880116],[112.630515,27.890561],[112.619684,27.899801],[112.611642,27.900293],[112.606937,27.918006],[112.599005,27.921176],[112.594738,27.931507],[112.596926,27.953477],[112.576686,27.959324],[112.574279,27.967848],[112.561368,27.980469],[112.553874,27.972601],[112.539486,27.975388],[112.531117,27.994126],[112.511806,27.994672],[112.508086,28.008874],[112.516401,28.018814],[112.486259,28.04022],[112.480241,28.056272],[112.468698,28.058893],[112.459125,28.051905],[112.443972,28.05731],[112.42291,28.049339],[112.413282,28.040657],[112.41011,28.031593],[112.415033,28.01521],[112.407101,28.001118],[112.398129,27.996857],[112.415361,27.99216],[112.411313,27.963258],[112.402341,27.966373],[112.389814,27.962111],[112.382757,27.967957],[112.371105,27.970033],[112.354037,27.965662],[112.342604,27.957193],[112.328217,27.963968],[112.313009,27.95916],[112.306663,27.971618],[112.298457,27.971235],[112.257647,27.95916],[112.245284,27.963695],[112.23035,27.961837],[112.223785,27.971399],[112.211094,27.95375],[112.199059,27.96222],[112.199223,27.969487],[112.18303,27.947083],[112.180897,27.93812],[112.173457,27.940743],[112.158851,27.928337],[112.160656,27.916912],[112.149551,27.908001],[112.137625,27.905705],[112.127669,27.911227],[112.11826,27.897614],[112.101137,27.893622],[112.093095,27.895919],[112.087734,27.908384],[112.060218,27.920028],[112.051246,27.919208],[112.04408,27.912156],[112.030513,27.914398],[112.017548,27.906307],[111.999714,27.907837]]]]}},{"type":"Feature","properties":{"adcode":430400,"name":"衡阳市","center":[112.607693,26.900358],"centroid":[112.579689,26.792402],"childrenNum":12,"level":"city","parent":{"adcode":430000},"subFeatureIndex":3,"acroutes":[100000,430000]},"geometry":{"type":"MultiPolygon","coordinates":[[[[112.995396,27.438309],[112.978109,27.439188],[112.955954,27.430293],[112.939597,27.426284],[112.9251,27.418871],[112.921818,27.409865],[112.924936,27.367074],[112.920177,27.356635],[112.901906,27.360536],[112.869958,27.356141],[112.863886,27.351196],[112.852999,27.355097],[112.834947,27.354382],[112.831118,27.338337],[112.815691,27.343777],[112.807868,27.338392],[112.799826,27.344327],[112.806282,27.348723],[112.80382,27.36202],[112.791566,27.36213],[112.77417,27.376359],[112.771818,27.392784],[112.76033,27.403988],[112.748404,27.39899],[112.735822,27.401517],[112.727507,27.394871],[112.715308,27.404263],[112.704093,27.407668],[112.685658,27.405691],[112.677397,27.419255],[112.678491,27.42892],[112.687244,27.437101],[112.69069,27.454121],[112.673075,27.456811],[112.659727,27.452309],[112.64627,27.464715],[112.639596,27.45983],[112.63046,27.466252],[112.615143,27.465978],[112.608305,27.455987],[112.592605,27.454999],[112.587244,27.437046],[112.576576,27.434466],[112.566893,27.441768],[112.553327,27.432379],[112.55453,27.424911],[112.538885,27.416674],[112.531007,27.430293],[112.521981,27.429194],[112.522418,27.420464],[112.508359,27.417004],[112.51279,27.403164],[112.50453,27.403988],[112.499005,27.397727],[112.49988,27.374931],[112.489596,27.371909],[112.485712,27.359877],[112.471871,27.372404],[112.459891,27.355152],[112.438118,27.344602],[112.432374,27.354218],[112.408523,27.36147],[112.368151,27.356086],[112.370503,27.363888],[112.358742,27.362459],[112.339267,27.365921],[112.331061,27.370206],[112.321543,27.363998],[112.312133,27.367074],[112.309125,27.360426],[112.299715,27.358723],[112.282593,27.337073],[112.287844,27.328939],[112.279857,27.31223],[112.267275,27.305084],[112.256116,27.310691],[112.254912,27.295684],[112.239048,27.287822],[112.233085,27.265388],[112.223785,27.261209],[112.213938,27.268908],[112.206225,27.285128],[112.20535,27.296564],[112.197691,27.295794],[112.190634,27.311791],[112.182374,27.309812],[112.174824,27.319651],[112.163883,27.324542],[112.153654,27.305689],[112.162844,27.284193],[112.163063,27.277321],[112.150535,27.265828],[112.1507,27.254609],[112.160054,27.247515],[112.154091,27.239375],[112.137899,27.237009],[112.127942,27.227658],[112.129529,27.220892],[112.112625,27.222322],[112.114211,27.210714],[112.107209,27.214125],[112.092165,27.205652],[112.08861,27.195143],[112.091235,27.185623],[112.076739,27.185183],[112.070666,27.191071],[112.058139,27.175442],[112.049003,27.150784],[112.05245,27.142856],[112.046596,27.132672],[112.056006,27.116649],[112.051684,27.102882],[112.056224,27.085754],[112.046925,27.077271],[112.05059,27.071102],[112.071815,27.064987],[112.078052,27.041792],[112.086859,27.033912],[112.086804,27.013246],[112.081006,27.008561],[112.060108,27.013026],[112.050152,27.006467],[112.043205,26.995663],[112.047143,26.975265],[112.019846,26.9649],[112.01629,26.955416],[112.007045,26.952658],[112.000644,26.943669],[111.979474,26.942291],[111.986366,26.950011],[111.983795,26.958228],[111.972526,26.958118],[111.961804,26.951169],[111.953598,26.955195],[111.9356,26.952217],[111.929802,26.93854],[111.917821,26.935176],[111.907427,26.924752],[111.89851,26.926627],[111.898237,26.96887],[111.894353,26.978243],[111.898401,26.986677],[111.881278,26.999632],[111.868696,27.013411],[111.863171,27.009774],[111.841946,27.008726],[111.817438,27.020962],[111.823237,27.036778],[111.81607,27.045428],[111.809178,27.046035],[111.807865,27.033141],[111.786913,27.039698],[111.776683,27.046586],[111.772525,27.058045],[111.753543,27.057329],[111.758029,27.062728],[111.737897,27.061571],[111.724768,27.069063],[111.712842,27.052316],[111.699276,27.046586],[111.68828,27.031377],[111.665796,27.031763],[111.659615,27.012144],[111.651518,27.008726],[111.649768,27.00112],[111.6577,26.986016],[111.649713,26.962915],[111.635271,26.963742],[111.622033,26.954202],[111.613663,26.959717],[111.604472,26.958393],[111.587569,26.96694],[111.581442,26.962143],[111.576463,26.945048],[111.567109,26.934845],[111.583137,26.925028],[111.583028,26.909031],[111.5891,26.896728],[111.578597,26.8831],[111.569078,26.884314],[111.564483,26.86958],[111.551026,26.860033],[111.550752,26.846952],[111.543586,26.840935],[111.549111,26.832324],[111.545938,26.821724],[111.549986,26.812338],[111.558083,26.808639],[111.575369,26.809357],[111.577229,26.79986],[111.588006,26.797596],[111.601245,26.785888],[111.618477,26.7913],[111.629637,26.789312],[111.638006,26.802344],[111.644516,26.803228],[111.642437,26.817252],[111.650862,26.840438],[111.66596,26.843309],[111.684615,26.833538],[111.701464,26.836188],[111.700589,26.843198],[111.712678,26.84916],[111.719243,26.847283],[111.731278,26.8326],[111.739046,26.832876],[111.746759,26.841487],[111.752285,26.831551],[111.745009,26.825534],[111.744735,26.812173],[111.753707,26.807038],[111.772142,26.80875],[111.771705,26.79986],[111.781278,26.789147],[111.797307,26.79257],[111.802504,26.801516],[111.820556,26.804498],[111.824057,26.798479],[111.817055,26.784011],[111.827504,26.780918],[111.831825,26.786164],[111.850206,26.789809],[111.859178,26.799584],[111.871486,26.796491],[111.874769,26.785888],[111.903325,26.751754],[111.917985,26.748936],[111.916399,26.733688],[111.927066,26.711032],[111.94036,26.699427],[111.949003,26.681519],[111.951902,26.664216],[111.959342,26.65642],[111.960983,26.645307],[111.973565,26.630929],[111.990196,26.624182],[111.997526,26.605101],[112.006005,26.596914],[112.014922,26.605322],[112.019736,26.619205],[112.013992,26.627556],[112.005513,26.624791],[111.995666,26.63939],[112.006498,26.648458],[112.028489,26.651831],[112.04583,26.643205],[112.05617,26.647961],[112.076903,26.64398],[112.093478,26.634026],[112.094189,26.645141],[112.10978,26.654043],[112.117822,26.650504],[112.115743,26.643371],[112.126356,26.63574],[112.151082,26.625731],[112.150317,26.617048],[112.141454,26.603386],[112.143916,26.593429],[112.158577,26.591825],[112.170557,26.585352],[112.168205,26.574674],[112.174715,26.571188],[112.169518,26.557078],[112.156389,26.555529],[112.149113,26.547173],[112.162735,26.539314],[112.147363,26.527469],[112.144737,26.504441],[112.15245,26.502725],[112.174223,26.524148],[112.19047,26.536879],[112.213118,26.548556],[112.227833,26.546453],[112.242713,26.535052],[112.243205,26.514073],[112.236695,26.505382],[112.211258,26.502725],[112.195339,26.486613],[112.1757,26.500178],[112.159999,26.493866],[112.159562,26.486336],[112.166509,26.477033],[112.152177,26.469668],[112.157975,26.465016],[112.161914,26.450727],[112.155295,26.444523],[112.143205,26.441477],[112.145612,26.431727],[112.152724,26.430065],[112.150098,26.416326],[112.153271,26.403139],[112.140634,26.407959],[112.141728,26.387068],[112.150152,26.38463],[112.148183,26.35736],[112.153161,26.349544],[112.158741,26.353036],[112.181498,26.34339],[112.177724,26.325925],[112.177942,26.305741],[112.190415,26.312229],[112.199004,26.30746],[112.20896,26.31356],[112.212461,26.30563],[112.205021,26.285275],[112.197308,26.277287],[112.200809,26.262365],[112.19605,26.229794],[112.190306,26.22369],[112.194901,26.206873],[112.192877,26.19394],[112.185929,26.185668],[112.195448,26.172011],[112.206115,26.165514],[112.217221,26.165459],[112.212571,26.151188],[112.222636,26.150799],[112.224332,26.138915],[112.231389,26.134417],[112.232428,26.117865],[112.257702,26.123308],[112.258523,26.130751],[112.266947,26.13114],[112.284453,26.143636],[112.290689,26.144024],[112.292385,26.134417],[112.304256,26.132917],[112.31186,26.148967],[112.310437,26.158574],[112.327068,26.161128],[112.33779,26.167569],[112.357046,26.161294],[112.364322,26.181282],[112.375044,26.190553],[112.377287,26.201544],[112.386641,26.205208],[112.395066,26.186168],[112.405788,26.184835],[112.429256,26.189721],[112.444574,26.175953],[112.450919,26.180394],[112.47953,26.175786],[112.485055,26.167957],[112.482046,26.160739],[112.48872,26.150911],[112.507812,26.159573],[112.50825,26.143858],[112.5129,26.135583],[112.524443,26.137471],[112.529092,26.147579],[112.554804,26.147245],[112.566565,26.158518],[112.578381,26.153632],[112.582047,26.15924],[112.576248,26.168346],[112.577451,26.182004],[112.572309,26.193384],[112.58057,26.208982],[112.581062,26.219083],[112.597802,26.220526],[112.602834,26.217085],[112.608961,26.198436],[112.623403,26.192108],[112.633688,26.163293],[112.630132,26.154409],[112.637299,26.138915],[112.654257,26.129251],[112.670668,26.127696],[112.658196,26.114976],[112.646161,26.112421],[112.642277,26.105977],[112.654913,26.101033],[112.665307,26.10981],[112.673787,26.111032],[112.676139,26.125974],[112.686423,26.123808],[112.688557,26.114198],[112.707704,26.122419],[112.710275,26.131751],[112.720395,26.125474],[112.735056,26.134583],[112.739979,26.144469],[112.746216,26.143802],[112.752507,26.129862],[112.760384,26.133084],[112.758743,26.149855],[112.768371,26.145524],[112.782157,26.146024],[112.783634,26.164237],[112.791402,26.166292],[112.78812,26.175342],[112.777179,26.177341],[112.775975,26.183892],[112.786041,26.196993],[112.79173,26.193218],[112.78987,26.179839],[112.795614,26.180116],[112.802616,26.19022],[112.809728,26.192163],[112.818535,26.186667],[112.818754,26.161794],[112.838557,26.155742],[112.846435,26.158296],[112.857923,26.154187],[112.870067,26.155797],[112.875866,26.1498],[112.891074,26.156519],[112.903601,26.148467],[112.920997,26.157963],[112.921052,26.174398],[112.930133,26.176785],[112.942606,26.170789],[112.949882,26.160184],[112.968645,26.154242],[112.984564,26.156575],[112.992989,26.162349],[113.008635,26.155631],[113.035659,26.172843],[113.034948,26.206651],[113.039926,26.213589],[113.025867,26.245276],[113.032103,26.25199],[113.045287,26.254542],[113.05207,26.248494],[113.068153,26.252933],[113.073514,26.24855],[113.091676,26.250103],[113.087136,26.273626],[113.103547,26.290544],[113.117059,26.287327],[113.119193,26.29304],[113.128821,26.29304],[113.130626,26.306572],[113.127344,26.31356],[113.142059,26.32587],[113.162683,26.324317],[113.173788,26.329696],[113.164762,26.344499],[113.168865,26.3491],[113.156556,26.36246],[113.167114,26.374266],[113.16044,26.387733],[113.163558,26.409566],[113.171874,26.412115],[113.179095,26.404967],[113.191239,26.406186],[113.212191,26.425246],[113.211699,26.433112],[113.192278,26.44552],[113.194904,26.451669],[113.210112,26.465182],[113.217388,26.462746],[113.226852,26.467065],[113.230079,26.482072],[113.214324,26.502448],[113.189653,26.506157],[113.179423,26.519388],[113.171655,26.521214],[113.160003,26.534222],[113.159182,26.541638],[113.179149,26.564438],[113.179259,26.578492],[113.186699,26.608088],[113.179587,26.638339],[113.188176,26.662447],[113.182979,26.687765],[113.160878,26.687875],[113.152289,26.700532],[113.134784,26.71258],[113.13916,26.71794],[113.122311,26.72319],[113.121381,26.73098],[113.131392,26.738053],[113.12904,26.74413],[113.115364,26.74413],[113.113066,26.753024],[113.101961,26.753245],[113.09556,26.759929],[113.097256,26.781636],[113.149062,26.792129],[113.142935,26.812504],[113.144138,26.834477],[113.153165,26.837568],[113.160495,26.827521],[113.183854,26.825202],[113.207103,26.829674],[113.206338,26.825478],[113.223679,26.820896],[113.224609,26.814437],[113.238066,26.805216],[113.258526,26.815486],[113.259784,26.827797],[113.252399,26.839224],[113.232869,26.860971],[113.227125,26.876423],[113.239106,26.877747],[113.24288,26.889279],[113.239708,26.894466],[113.254751,26.900259],[113.257104,26.917691],[113.266458,26.918408],[113.278329,26.928447],[113.280955,26.939974],[113.245014,26.93832],[113.235331,26.951721],[113.225594,26.956298],[113.221546,26.974549],[113.226852,26.994671],[113.21892,27.002939],[113.224937,27.012474],[113.235714,27.014789],[113.23462,27.021403],[113.220014,27.024434],[113.215856,27.0408],[113.198022,27.04069],[113.199171,27.056888],[113.193865,27.076059],[113.175101,27.088838],[113.170779,27.099027],[113.164543,27.101285],[113.16799,27.126175],[113.193482,27.1357],[113.196053,27.14181],[113.219467,27.131736],[113.236042,27.145224],[113.244795,27.139994],[113.245944,27.151609],[113.257815,27.160141],[113.260058,27.173186],[113.280298,27.166636],[113.283964,27.178634],[113.271929,27.205707],[113.255408,27.223642],[113.248406,27.23943],[113.23183,27.237339],[113.182979,27.240915],[113.173734,27.233489],[113.164324,27.236019],[113.148296,27.251695],[113.144138,27.249275],[113.133252,27.229638],[113.127508,27.207358],[113.115473,27.205597],[113.107814,27.225238],[113.087847,27.235469],[113.092606,27.238274],[113.082431,27.253895],[113.085878,27.266433],[113.068427,27.280949],[113.051031,27.287492],[113.04381,27.309647],[113.048843,27.320915],[113.032541,27.329269],[113.033306,27.345041],[113.042223,27.350921],[113.025265,27.367239],[113.021545,27.378337],[113.024171,27.385807],[113.002015,27.392729],[112.994247,27.407064],[112.999225,27.435619],[112.995396,27.438309]]]]}},{"type":"Feature","properties":{"adcode":430500,"name":"邵阳市","center":[111.46923,27.237842],"centroid":[110.880659,26.912035],"childrenNum":12,"level":"city","parent":{"adcode":430000},"subFeatureIndex":4,"acroutes":[100000,430000]},"geometry":{"type":"MultiPolygon","coordinates":[[[[111.008573,26.358857],[111.01656,26.366007],[111.025094,26.384575],[111.019022,26.391058],[111.019186,26.401033],[111.031768,26.432503],[111.044952,26.440923],[111.043694,26.451225],[111.052665,26.457041],[111.060269,26.473766],[111.05644,26.486613],[111.067217,26.505548],[111.063278,26.526528],[111.06656,26.541306],[111.063934,26.558406],[111.067107,26.577274],[111.073562,26.587841],[111.088716,26.588893],[111.104744,26.585905],[111.11388,26.609249],[111.10923,26.617435],[111.127447,26.623076],[111.137129,26.610632],[111.133191,26.590773],[111.127118,26.577496],[111.12586,26.553924],[111.142272,26.541306],[111.153978,26.527026],[111.15923,26.515734],[111.165959,26.511748],[111.154416,26.500399],[111.158847,26.49442],[111.15551,26.48246],[111.168038,26.474154],[111.184668,26.470499],[111.181057,26.463355],[111.201189,26.457318],[111.203322,26.462856],[111.229635,26.481131],[111.251353,26.483844],[111.259723,26.479913],[111.263388,26.493423],[111.271867,26.499403],[111.278268,26.490212],[111.288771,26.492316],[111.296922,26.511748],[111.296047,26.526196],[111.288498,26.557078],[111.297031,26.567758],[111.297688,26.576943],[111.304581,26.58336],[111.30387,26.60405],[111.306058,26.619758],[111.314263,26.626616],[111.312568,26.639003],[111.301244,26.644201],[111.299384,26.660677],[111.293694,26.67284],[111.281112,26.678699],[111.276244,26.68887],[111.30294,26.700035],[111.309067,26.710922],[111.32143,26.714238],[111.317218,26.733191],[111.324001,26.737721],[111.329417,26.757609],[111.329198,26.772136],[111.321485,26.783127],[111.32411,26.788318],[111.315139,26.802565],[111.322524,26.813111],[111.321922,26.820123],[111.329854,26.836685],[111.349712,26.851533],[111.349657,26.859812],[111.366397,26.864944],[111.372907,26.858211],[111.392437,26.863013],[111.406441,26.858211],[111.419625,26.867814],[111.430019,26.867924],[111.43817,26.86086],[111.4455,26.867593],[111.460106,26.867097],[111.462513,26.861081],[111.471485,26.861964],[111.482535,26.856776],[111.495227,26.860695],[111.507973,26.859536],[111.517218,26.86511],[111.528269,26.865],[111.53363,26.847117],[111.543586,26.840935],[111.550752,26.846952],[111.551026,26.860033],[111.564483,26.86958],[111.569078,26.884314],[111.578597,26.8831],[111.5891,26.896728],[111.583028,26.909031],[111.583137,26.925028],[111.567109,26.934845],[111.576463,26.945048],[111.581442,26.962143],[111.587569,26.96694],[111.604472,26.958393],[111.613663,26.959717],[111.622033,26.954202],[111.635271,26.963742],[111.649713,26.962915],[111.6577,26.986016],[111.649768,27.00112],[111.651518,27.008726],[111.659615,27.012144],[111.665796,27.031763],[111.68828,27.031377],[111.699276,27.046586],[111.712842,27.052316],[111.724768,27.069063],[111.737897,27.061571],[111.758029,27.062728],[111.753543,27.057329],[111.772525,27.058045],[111.776683,27.046586],[111.786913,27.039698],[111.807865,27.033141],[111.809178,27.046035],[111.81607,27.045428],[111.823237,27.036778],[111.817438,27.020962],[111.841946,27.008726],[111.863171,27.009774],[111.868696,27.013411],[111.881278,26.999632],[111.898401,26.986677],[111.894353,26.978243],[111.898237,26.96887],[111.89851,26.926627],[111.907427,26.924752],[111.917821,26.935176],[111.929802,26.93854],[111.9356,26.952217],[111.953598,26.955195],[111.961804,26.951169],[111.972526,26.958118],[111.983795,26.958228],[111.986366,26.950011],[111.979474,26.942291],[112.000644,26.943669],[112.007045,26.952658],[112.01629,26.955416],[112.019846,26.9649],[112.047143,26.975265],[112.043205,26.995663],[112.050152,27.006467],[112.060108,27.013026],[112.081006,27.008561],[112.086804,27.013246],[112.086859,27.033912],[112.078052,27.041792],[112.071815,27.064987],[112.05059,27.071102],[112.046925,27.077271],[112.056224,27.085754],[112.051684,27.102882],[112.056006,27.116649],[112.046596,27.132672],[112.05245,27.142856],[112.049003,27.150784],[112.058139,27.175442],[112.070666,27.191071],[112.076739,27.185183],[112.091235,27.185623],[112.08861,27.195143],[112.092165,27.205652],[112.085327,27.204002],[112.068424,27.218636],[112.069244,27.235909],[112.065196,27.250815],[112.062406,27.285843],[112.051301,27.292385],[112.041071,27.289142],[112.025152,27.3036],[112.01804,27.317562],[111.990797,27.317342],[111.98571,27.332731],[111.990305,27.341579],[111.970502,27.357514],[111.940852,27.369217],[111.909451,27.388939],[111.907318,27.39542],[111.912843,27.410304],[111.892766,27.426833],[111.882537,27.438364],[111.855294,27.461147],[111.840195,27.456646],[111.835162,27.44605],[111.819517,27.44929],[111.813609,27.45434],[111.810764,27.471357],[111.803598,27.474815],[111.796377,27.468173],[111.790195,27.470479],[111.78746,27.494627],[111.744079,27.499401],[111.73095,27.518222],[111.717766,27.516576],[111.692985,27.533857],[111.690742,27.523708],[111.67537,27.537149],[111.668915,27.537149],[111.654035,27.514765],[111.643914,27.520142],[111.638663,27.537917],[111.650096,27.534022],[111.652831,27.540111],[111.641672,27.54779],[111.639866,27.559198],[111.630621,27.553056],[111.625917,27.556127],[111.635599,27.562379],[111.641398,27.574663],[111.635162,27.578776],[111.625479,27.575212],[111.612405,27.580695],[111.620665,27.571757],[111.615577,27.566163],[111.6077,27.57587],[111.594625,27.582944],[111.589046,27.606574],[111.574056,27.607725],[111.568148,27.61688],[111.567984,27.627075],[111.560927,27.630583],[111.553597,27.626034],[111.542656,27.609644],[111.522251,27.605532],[111.489373,27.594238],[111.477831,27.578666],[111.468257,27.579599],[111.457918,27.595445],[111.441944,27.597473],[111.430347,27.59062],[111.414373,27.575212],[111.403979,27.557388],[111.388388,27.544938],[111.374603,27.542963],[111.376518,27.532815],[111.367765,27.524915],[111.357097,27.522885],[111.349822,27.537039],[111.322141,27.546858],[111.300861,27.567096],[111.278377,27.555798],[111.270718,27.541756],[111.256112,27.542799],[111.244624,27.52508],[111.223782,27.536161],[111.220773,27.551739],[111.204143,27.552781],[111.197414,27.549161],[111.182863,27.557005],[111.182151,27.56375],[111.169515,27.562653],[111.163442,27.576473],[111.150094,27.582176],[111.143147,27.578008],[111.130237,27.581408],[111.116287,27.577186],[111.106932,27.590729],[111.080291,27.588756],[111.07411,27.591442],[111.070827,27.620607],[111.059941,27.631295],[111.040247,27.631843],[111.02575,27.63568],[111.008081,27.625869],[110.994076,27.630144],[110.998453,27.639352],[110.994733,27.652395],[110.983792,27.660121],[110.945717,27.653819],[110.91749,27.656395],[110.882916,27.650696],[110.869185,27.655463],[110.855564,27.647353],[110.852336,27.627568],[110.857314,27.621375],[110.845662,27.62428],[110.847632,27.608986],[110.854579,27.601804],[110.853485,27.592045],[110.824328,27.578831],[110.808682,27.563366],[110.799437,27.559418],[110.7868,27.560515],[110.776898,27.574005],[110.767052,27.581299],[110.755837,27.596815],[110.746647,27.603833],[110.737949,27.600708],[110.743693,27.617318],[110.741067,27.62565],[110.734174,27.616386],[110.714426,27.616003],[110.710542,27.606958],[110.674053,27.60005],[110.653047,27.57417],[110.652773,27.565834],[110.638112,27.555908],[110.632642,27.536106],[110.648233,27.529578],[110.68029,27.497042],[110.68401,27.487877],[110.684666,27.468722],[110.69331,27.455822],[110.688222,27.443854],[110.674108,27.434575],[110.663113,27.420683],[110.659666,27.396793],[110.649218,27.365206],[110.636526,27.353613],[110.632204,27.343283],[110.614863,27.324103],[110.606548,27.32108],[110.609994,27.309537],[110.606384,27.301841],[110.609064,27.288977],[110.598725,27.281444],[110.585104,27.278585],[110.573998,27.281059],[110.553922,27.308218],[110.540847,27.305194],[110.524272,27.293375],[110.526405,27.289911],[110.511635,27.273746],[110.483517,27.262144],[110.462127,27.247075],[110.456274,27.2133],[110.443035,27.201251],[110.424053,27.19949],[110.387127,27.218801],[110.375584,27.223037],[110.352116,27.19905],[110.355891,27.175277],[110.342707,27.150508],[110.331766,27.151444],[110.325803,27.158765],[110.31437,27.157939],[110.304632,27.166966],[110.26705,27.153866],[110.24949,27.151059],[110.226514,27.130359],[110.200474,27.118191],[110.194183,27.102111],[110.204413,27.092033],[110.208352,27.081292],[110.201404,27.061902],[110.162619,27.04642],[110.155069,27.037714],[110.15031,27.022891],[110.153647,26.998419],[110.146262,26.986898],[110.125529,26.984803],[110.116284,26.978022],[110.104796,26.951941],[110.089697,26.948743],[110.075911,26.941684],[110.072137,26.932032],[110.09741,26.906383],[110.093253,26.891155],[110.078209,26.881996],[110.063548,26.882051],[110.055944,26.876202],[110.048668,26.86075],[110.042104,26.835029],[110.048723,26.825037],[110.057421,26.822718],[110.056546,26.80886],[110.061634,26.793509],[110.068581,26.784618],[110.063493,26.769927],[110.068253,26.759653],[110.061688,26.760316],[110.064095,26.750925],[110.04927,26.747555],[110.056546,26.740207],[110.05031,26.735622],[110.047465,26.724681],[110.060813,26.717553],[110.067323,26.718382],[110.072082,26.700145],[110.065189,26.695392],[110.044183,26.6981],[110.036907,26.681961],[110.021863,26.668251],[110.020331,26.662889],[110.002005,26.666593],[110.007476,26.673116],[109.997738,26.674277],[109.987618,26.685333],[109.963603,26.691855],[109.950036,26.68887],[109.941939,26.67776],[109.934062,26.673724],[109.91404,26.676212],[109.901075,26.66803],[109.898942,26.655591],[109.885429,26.653822],[109.858241,26.643427],[109.851458,26.621804],[109.83067,26.621528],[109.826841,26.60582],[109.856819,26.580926],[109.861688,26.583637],[109.872081,26.571022],[109.864368,26.561007],[109.862672,26.539867],[109.8723,26.538871],[109.892541,26.525477],[109.879685,26.517395],[109.883187,26.509977],[109.879357,26.497022],[109.862344,26.486834],[109.856272,26.465182],[109.875418,26.468173],[109.891392,26.459367],[109.902826,26.461804],[109.919018,26.474652],[109.932585,26.475981],[109.934883,26.456986],[109.955014,26.446905],[109.950583,26.43699],[109.96683,26.428016],[109.98729,26.432447],[109.979412,26.40735],[109.978646,26.388011],[110.012235,26.372492],[110.011524,26.364622],[110.017706,26.347548],[110.013001,26.335074],[110.009281,26.304021],[109.995933,26.294981],[109.984281,26.279118],[109.990408,26.27285],[109.995331,26.258703],[109.988821,26.245165],[109.99276,26.238617],[109.974379,26.218362],[109.966228,26.195494],[109.98439,26.17995],[110.005725,26.185779],[110.016721,26.184225],[110.030233,26.166125],[110.041557,26.162461],[110.051568,26.169235],[110.068417,26.168069],[110.084008,26.171511],[110.098723,26.169123],[110.094402,26.147134],[110.100474,26.133028],[110.074434,26.083087],[110.072137,26.063916],[110.064916,26.050022],[110.073176,26.040295],[110.083406,26.039016],[110.101021,26.020172],[110.112509,26.034792],[110.129632,26.029233],[110.140463,26.020394],[110.156382,26.018504],[110.165846,26.023841],[110.172958,26.045019],[110.181656,26.06047],[110.190956,26.067639],[110.201185,26.066139],[110.212126,26.043074],[110.234118,26.032735],[110.245223,26.022284],[110.251295,26.003715],[110.245824,25.96857],[110.261689,25.961395],[110.287947,25.966901],[110.305124,25.967346],[110.325529,25.975633],[110.335322,25.992483],[110.357969,26.046465],[110.353265,26.05469],[110.373232,26.078531],[110.377116,26.094421],[110.400365,26.116476],[110.414534,26.125752],[110.427171,26.138027],[110.437948,26.153965],[110.45693,26.164404],[110.474108,26.180172],[110.490519,26.16557],[110.500147,26.169734],[110.517543,26.186834],[110.531055,26.209371],[110.542653,26.221137],[110.546646,26.233568],[110.546099,26.25726],[110.555235,26.286384],[110.569349,26.289601],[110.584064,26.296922],[110.595114,26.318384],[110.612346,26.333688],[110.62285,26.330084],[110.625804,26.315667],[110.643747,26.308458],[110.667215,26.317608],[110.697795,26.308735],[110.709502,26.293151],[110.720935,26.294205],[110.732533,26.311785],[110.741778,26.313893],[110.749491,26.301082],[110.750038,26.290489],[110.742817,26.276122],[110.735213,26.271019],[110.758189,26.255208],[110.759119,26.248716],[110.78226,26.257482],[110.814645,26.258814],[110.841177,26.257316],[110.855619,26.268134],[110.914919,26.276344],[110.924328,26.26303],[110.921593,26.254875],[110.929962,26.255651],[110.9304,26.264362],[110.939755,26.286662],[110.936035,26.305352],[110.925422,26.318717],[110.943912,26.326702],[110.950531,26.356972],[110.944842,26.373601],[110.958956,26.382746],[110.974547,26.385572],[110.983628,26.378035],[110.991888,26.363568],[111.008573,26.358857]]]]}},{"type":"Feature","properties":{"adcode":430600,"name":"岳阳市","center":[113.132855,29.37029],"centroid":[113.259661,29.064701],"childrenNum":9,"level":"city","parent":{"adcode":430000},"subFeatureIndex":5,"acroutes":[100000,430000]},"geometry":{"type":"MultiPolygon","coordinates":[[[[112.315744,29.524298],[112.320066,29.516007],[112.331116,29.51057],[112.324442,29.480416],[112.328271,29.450091],[112.342002,29.444435],[112.350974,29.453108],[112.366182,29.458441],[112.366783,29.442549],[112.386149,29.426871],[112.388829,29.420997],[112.386641,29.406016],[112.392057,29.396476],[112.423075,29.371734],[112.439924,29.360627],[112.464267,29.35351],[112.485766,29.342941],[112.490963,29.337602],[112.496981,29.317052],[112.502068,29.312198],[112.532429,29.308907],[112.547364,29.301786],[112.560219,29.304591],[112.579421,29.303674],[112.590417,29.317861],[112.611806,29.333287],[112.634454,29.335984],[112.652561,29.321421],[112.66476,29.300383],[112.673622,29.306264],[112.680789,29.294988],[112.689268,29.295743],[112.699881,29.287381],[112.683305,29.27497],[112.682813,29.269573],[112.693699,29.253976],[112.679093,29.2448],[112.681664,29.230441],[112.676358,29.224718],[112.680953,29.214027],[112.677561,29.205388],[112.68243,29.192265],[112.693207,29.192589],[112.711259,29.185352],[112.715855,29.18735],[112.724553,29.177628],[112.741949,29.168283],[112.75661,29.169958],[112.775592,29.176602],[112.793864,29.190915],[112.810384,29.185514],[112.813448,29.178654],[112.798513,29.159802],[112.812901,29.1524],[112.88161,29.162773],[112.901085,29.154615],[112.924663,29.149429],[112.92707,29.109061],[112.937737,29.078139],[112.93905,29.065541],[112.949389,29.060783],[112.9344,29.037311],[112.927945,29.023031],[112.891402,28.999388],[112.876085,28.984075],[112.87242,28.962967],[112.847967,28.935521],[112.83812,28.929295],[112.811588,28.921552],[112.797474,28.9137],[112.784181,28.911967],[112.773185,28.90276],[112.722911,28.883478],[112.685165,28.879741],[112.677452,28.871235],[112.668371,28.85043],[112.659837,28.840839],[112.664924,28.821057],[112.672966,28.811517],[112.671708,28.791568],[112.641784,28.789453],[112.619137,28.778555],[112.617495,28.770042],[112.606117,28.758002],[112.603764,28.746884],[112.58057,28.73967],[112.569082,28.731641],[112.552233,28.72958],[112.555843,28.719652],[112.548239,28.712328],[112.534563,28.70956],[112.526412,28.702561],[112.525318,28.678357],[112.521106,28.665493],[112.510602,28.654799],[112.533797,28.640412],[112.544136,28.639434],[112.552561,28.644104],[112.563666,28.629389],[112.57406,28.623796],[112.580515,28.629715],[112.588721,28.62738],[112.585001,28.620918],[112.590143,28.601692],[112.582813,28.590123],[112.574388,28.585125],[112.563721,28.570946],[112.562462,28.563556],[112.582539,28.556873],[112.591948,28.542962],[112.609727,28.540788],[112.629366,28.5472],[112.635439,28.559046],[112.648841,28.564263],[112.658688,28.580507],[112.668371,28.584256],[112.675154,28.581214],[112.684016,28.596369],[112.705351,28.599574],[112.717496,28.596206],[112.713229,28.587189],[112.716456,28.579203],[112.726194,28.581702],[112.736095,28.568229],[112.726522,28.557199],[112.701741,28.552417],[112.688283,28.54432],[112.685384,28.525407],[112.700428,28.519699],[112.714542,28.510621],[112.731664,28.507414],[112.746872,28.510458],[112.753874,28.518014],[112.757704,28.529755],[112.772693,28.546385],[112.796435,28.558503],[112.808798,28.559046],[112.788831,28.535027],[112.792058,28.523015],[112.808579,28.519319],[112.815581,28.527798],[112.822419,28.528396],[112.822529,28.512796],[112.845341,28.510621],[112.852617,28.512524],[112.872365,28.500618],[112.87149,28.519156],[112.891293,28.524754],[112.898733,28.517525],[112.921271,28.520297],[112.939816,28.508501],[112.965637,28.521167],[112.978656,28.52345],[112.974882,28.506979],[112.977726,28.498552],[112.960768,28.477075],[112.974006,28.465274],[112.99184,28.460923],[113.019028,28.47305],[113.027781,28.483219],[113.041403,28.484905],[113.063722,28.505294],[113.067935,28.519264],[113.07904,28.521873],[113.085002,28.508229],[113.0966,28.50812],[113.111917,28.499313],[113.130462,28.498498],[113.132103,28.490777],[113.128657,28.473975],[113.154313,28.470875],[113.169904,28.480446],[113.171381,28.492408],[113.18544,28.503391],[113.183088,28.510132],[113.185933,28.529211],[113.19474,28.541549],[113.19392,28.55008],[113.200758,28.555569],[113.194685,28.56649],[113.186097,28.567957],[113.189653,28.580181],[113.183252,28.596858],[113.195014,28.603648],[113.215473,28.620809],[113.212957,28.632647],[113.216458,28.638077],[113.234729,28.646438],[113.233635,28.661639],[113.243592,28.656156],[113.245944,28.640629],[113.251797,28.629715],[113.258854,28.627597],[113.27253,28.631398],[113.283635,28.638728],[113.310003,28.633136],[113.316513,28.628629],[113.320342,28.615759],[113.332213,28.618963],[113.349226,28.616573],[113.358581,28.622384],[113.360113,28.631453],[113.375813,28.643343],[113.384785,28.644538],[113.411809,28.632267],[113.4245,28.636068],[113.42078,28.609513],[113.414599,28.590883],[113.424336,28.578715],[113.430408,28.590286],[113.446492,28.593925],[113.454369,28.591046],[113.462739,28.596532],[113.474391,28.579801],[113.491349,28.570457],[113.500923,28.559155],[113.507378,28.536929],[113.51542,28.537038],[113.52822,28.528287],[113.547258,28.52508],[113.558035,28.533179],[113.575923,28.536386],[113.598133,28.51198],[113.615311,28.495725],[113.635825,28.482621],[113.64972,28.470005],[113.661427,28.45445],[113.657324,28.447706],[113.676963,28.442049],[113.704643,28.422192],[113.717773,28.424042],[113.729698,28.441287],[113.7617,28.451405],[113.7739,28.451024],[113.78495,28.457551],[113.806394,28.458638],[113.817554,28.466851],[113.824885,28.484089],[113.832981,28.489037],[113.832434,28.498878],[113.844414,28.523885],[113.858473,28.532255],[113.876471,28.518884],[113.889546,28.515622],[113.903222,28.528613],[113.917883,28.525461],[113.935443,28.531385],[113.941242,28.526385],[113.950979,28.53644],[113.962467,28.542309],[113.975979,28.564752],[113.995782,28.564915],[114.013561,28.554591],[114.015038,28.545679],[114.025432,28.542798],[114.040038,28.551004],[114.051745,28.544374],[114.065968,28.547689],[114.073901,28.555188],[114.086756,28.555895],[114.094688,28.562252],[114.094798,28.570076],[114.104535,28.583115],[114.118704,28.586863],[114.132107,28.607178],[114.12226,28.623253],[114.132818,28.641823],[114.12959,28.645895],[114.133091,28.671681],[114.123299,28.68221],[114.122369,28.689483],[114.128222,28.701041],[114.139984,28.702941],[114.149339,28.723775],[114.146603,28.734571],[114.151964,28.742436],[114.157107,28.761473],[114.15377,28.770747],[114.137468,28.779748],[114.140258,28.789182],[114.151964,28.801597],[114.153934,28.82935],[114.149503,28.83504],[114.142938,28.827995],[114.134459,28.826965],[114.124885,28.843277],[114.097478,28.83374],[114.080411,28.833252],[114.069196,28.847016],[114.059677,28.849726],[114.062303,28.856716],[114.056395,28.870531],[114.066844,28.884507],[114.06017,28.902381],[114.048682,28.908122],[114.040585,28.906551],[114.028332,28.89117],[114.023955,28.907689],[114.014601,28.91787],[114.00541,28.917815],[114.003933,28.926479],[114.009623,28.94532],[114.008857,28.955389],[113.985115,28.948839],[113.973791,28.937903],[113.966734,28.944292],[113.955684,28.978392],[113.961482,28.996953],[113.94622,29.017946],[113.948189,29.031577],[113.946001,29.044775],[113.933364,29.045965],[113.914874,29.036283],[113.911701,29.030766],[113.895344,29.029468],[113.876581,29.03823],[113.876088,29.056997],[113.881832,29.065433],[113.868648,29.065811],[113.85262,29.058674],[113.831558,29.069326],[113.837029,29.08679],[113.827182,29.102467],[113.815968,29.105331],[113.775595,29.095223],[113.76646,29.089222],[113.765475,29.079924],[113.749447,29.060945],[113.740147,29.058728],[113.734184,29.06446],[113.726252,29.083654],[113.732105,29.105061],[113.722751,29.104737],[113.709512,29.092628],[113.706339,29.082897],[113.696328,29.077653],[113.685606,29.082302],[113.690584,29.11452],[113.68298,29.132192],[113.672586,29.136191],[113.667991,29.143755],[113.670344,29.154345],[113.662028,29.167257],[113.67193,29.179465],[113.6803,29.182435],[113.693812,29.201824],[113.690092,29.230818],[113.681886,29.23395],[113.665803,29.232222],[113.660059,29.224502],[113.646438,29.231412],[113.635223,29.25063],[113.609621,29.251547],[113.606886,29.267631],[113.613615,29.272433],[113.633035,29.318401],[113.643429,29.326869],[113.661044,29.333449],[113.665967,29.347039],[113.660934,29.368229],[113.670015,29.384564],[113.691897,29.392703],[113.710716,29.393566],[113.723243,29.389631],[113.731886,29.394805],[113.741733,29.41286],[113.736974,29.426278],[113.754479,29.441418],[113.754917,29.447559],[113.73774,29.470345],[113.724775,29.473307],[113.707269,29.485747],[113.68856,29.509655],[113.677619,29.513531],[113.673024,29.510354],[113.643374,29.507824],[113.635332,29.510031],[113.631394,29.52349],[113.654479,29.530865],[113.657269,29.537001],[113.669031,29.535709],[113.680847,29.539369],[113.681284,29.548465],[113.691241,29.547765],[113.70158,29.555515],[113.709293,29.554331],[113.713943,29.570582],[113.735661,29.5765],[113.741022,29.591564],[113.728549,29.598234],[113.722915,29.610821],[113.708418,29.608992],[113.704096,29.618673],[113.702783,29.634752],[113.688068,29.640828],[113.679479,29.635129],[113.671602,29.640774],[113.680354,29.641366],[113.667116,29.664269],[113.668702,29.671311],[113.662357,29.684533],[113.652674,29.683565],[113.637849,29.669859],[113.599774,29.670934],[113.575595,29.674912],[113.547148,29.675396],[113.538396,29.683673],[113.540146,29.699634],[113.558472,29.727036],[113.561153,29.73907],[113.555901,29.763669],[113.550978,29.76818],[113.560004,29.783161],[113.567827,29.786544],[113.561919,29.79159],[113.569413,29.804582],[113.57565,29.807964],[113.565256,29.81258],[113.577236,29.818538],[113.580901,29.835659],[113.571547,29.848913],[113.517881,29.812419],[113.4931,29.786597],[113.456667,29.759211],[113.438614,29.751638],[113.401798,29.724082],[113.377345,29.703181],[113.326196,29.647818],[113.298078,29.613833],[113.27729,29.595114],[113.272257,29.580858],[113.256611,29.566492],[113.222421,29.543729],[113.182103,29.485586],[113.155736,29.457148],[113.145342,29.449337],[113.132541,29.457364],[113.113558,29.456663],[113.099992,29.45968],[113.102672,29.443034],[113.090582,29.43075],[113.080735,29.434091],[113.075976,29.450199],[113.072803,29.482785],[113.064707,29.512454],[113.05765,29.522467],[113.0344,29.523598],[113.018755,29.516169],[112.990308,29.497971],[112.969192,29.469052],[112.950155,29.472876],[112.943317,29.493879],[112.937409,29.527097],[112.92707,29.556161],[112.924006,29.571658],[112.911862,29.606841],[112.912026,29.616145],[112.945396,29.647495],[112.965418,29.658947],[112.976195,29.672117],[113.004969,29.693777],[113.015254,29.710918],[113.025046,29.748631],[113.030899,29.762272],[113.02614,29.772798],[113.011807,29.767696],[113.003492,29.755237],[112.979258,29.737619],[112.957814,29.694153],[112.944794,29.682759],[112.933197,29.683243],[112.927015,29.692164],[112.927343,29.708393],[112.932048,29.739929],[112.929914,29.755344],[112.922748,29.76732],[112.899717,29.781711],[112.889433,29.785738],[112.870013,29.786007],[112.843645,29.771079],[112.815417,29.746643],[112.793918,29.7359],[112.806117,29.726069],[112.791785,29.713712],[112.795176,29.697646],[112.784837,29.693562],[112.788557,29.679911],[112.765964,29.675073],[112.763831,29.664806],[112.735439,29.646259],[112.730242,29.654216],[112.718973,29.652549],[112.71394,29.637548],[112.698677,29.619964],[112.699005,29.610767],[112.688995,29.602376],[112.68697,29.592747],[112.678984,29.58952],[112.673404,29.600009],[112.660275,29.599525],[112.650646,29.592478],[112.640198,29.607916],[112.624716,29.616522],[112.607758,29.608024],[112.607156,29.612273],[112.589651,29.620233],[112.5722,29.62389],[112.565143,29.62077],[112.540799,29.600816],[112.535219,29.599687],[112.505241,29.610982],[112.499114,29.629267],[112.481992,29.633462],[112.465854,29.631418],[112.456663,29.635935],[112.43965,29.633784],[112.427287,29.616952],[112.424825,29.598665],[112.407812,29.577845],[112.402177,29.576393],[112.397254,29.564125],[112.391838,29.567837],[112.370284,29.542222],[112.332046,29.544751],[112.320066,29.540553],[112.315744,29.524298]]],[[[112.929367,29.774086],[112.937901,29.766569],[112.939597,29.779993],[112.933744,29.789282],[112.919685,29.799697],[112.901194,29.803186],[112.886533,29.796422],[112.898733,29.793255],[112.929367,29.774086]]]]}},{"type":"Feature","properties":{"adcode":430700,"name":"常德市","center":[111.691347,29.040225],"centroid":[111.524565,29.299744],"childrenNum":9,"level":"city","parent":{"adcode":430000},"subFeatureIndex":6,"acroutes":[100000,430000]},"geometry":{"type":"MultiPolygon","coordinates":[[[[112.283413,29.495225],[112.278216,29.50987],[112.281991,29.537109],[112.291564,29.54276],[112.302724,29.566008],[112.303216,29.585485],[112.295175,29.59533],[112.282046,29.596244],[112.251958,29.61152],[112.241728,29.610122],[112.234398,29.615823],[112.228271,29.62959],[112.2321,29.640559],[112.24419,29.659592],[112.236094,29.658463],[112.218205,29.64513],[112.220448,29.637226],[112.206717,29.635075],[112.199441,29.629859],[112.198293,29.617436],[112.18582,29.634322],[112.184015,29.648033],[112.178161,29.656635],[112.16454,29.662333],[112.150535,29.654538],[112.144026,29.657441],[112.124988,29.657011],[112.118478,29.66271],[112.111531,29.659646],[112.107483,29.671149],[112.091892,29.685661],[112.087461,29.681738],[112.065469,29.681792],[112.059944,29.695765],[112.064485,29.710327],[112.074003,29.717097],[112.073292,29.734718],[112.07641,29.743474],[112.065907,29.754646],[112.06443,29.769844],[112.054693,29.758835],[112.064704,29.745945],[112.050754,29.749168],[112.045557,29.758406],[112.031224,29.762272],[112.00978,29.77806],[111.99129,29.782785],[111.987078,29.793953],[111.977067,29.790517],[111.954856,29.796744],[111.951574,29.814244],[111.96525,29.831151],[111.960929,29.83743],[111.936202,29.832492],[111.919298,29.84242],[111.914594,29.852669],[111.880622,29.860019],[111.86339,29.856532],[111.849987,29.870964],[111.839648,29.876811],[111.828981,29.873968],[111.830677,29.887914],[111.810326,29.89376],[111.809615,29.902288],[111.794626,29.90572],[111.757427,29.920091],[111.736475,29.919608],[111.724878,29.915533],[111.718915,29.90084],[111.705403,29.896764],[111.705074,29.89006],[111.68177,29.884535],[111.66235,29.885822],[111.651464,29.892956],[111.621704,29.89494],[111.597962,29.889362],[111.584013,29.898051],[111.577886,29.89435],[111.56596,29.898534],[111.551409,29.895208],[111.546102,29.904218],[111.538444,29.904647],[111.527448,29.925667],[111.514483,29.927704],[111.483465,29.91816],[111.474931,29.919072],[111.463553,29.9269],[111.445555,29.924702],[111.437787,29.93001],[111.419953,29.916391],[111.405347,29.911136],[111.39085,29.914836],[111.382809,29.92363],[111.390139,29.937515],[111.378323,29.937247],[111.383301,29.945878],[111.37515,29.954401],[111.351682,29.951399],[111.347141,29.941965],[111.342108,29.945342],[111.335762,29.963352],[111.322141,29.978304],[111.318749,29.971873],[111.29725,29.9902],[111.297688,30.004612],[111.286091,30.011309],[111.266999,30.011416],[111.25562,30.034555],[111.242217,30.040393],[111.199712,30.040982],[111.179744,30.044249],[111.178979,30.0405],[111.106659,30.047729],[111.078924,30.049122],[111.031549,30.048854],[111.005838,30.054476],[110.998398,30.059349],[110.970936,30.058974],[110.929908,30.063418],[110.923015,30.075732],[110.925203,30.094521],[110.924273,30.111327],[110.897905,30.109828],[110.873945,30.113414],[110.858026,30.118551],[110.853048,30.125721],[110.836089,30.122671],[110.814371,30.125989],[110.802993,30.11443],[110.788332,30.119996],[110.769568,30.12021],[110.746373,30.112611],[110.753102,30.101319],[110.748999,30.088312],[110.756001,30.083013],[110.75529,30.052816],[110.742106,30.041785],[110.722358,30.039643],[110.712347,30.033163],[110.694075,30.041517],[110.68215,30.053834],[110.686362,30.059135],[110.659611,30.071235],[110.650968,30.077606],[110.62657,30.063793],[110.597631,30.054423],[110.576405,30.059081],[110.564753,30.054369],[110.531329,30.061116],[110.508189,30.050407],[110.501022,30.055226],[110.495989,30.040232],[110.499819,30.02695],[110.491558,30.019719],[110.504687,30.008791],[110.520114,30.001773],[110.547248,29.999576],[110.557204,29.986931],[110.551077,29.979697],[110.535267,29.975089],[110.517324,29.961369],[110.508079,29.944109],[110.506766,29.919018],[110.498068,29.910063],[110.50786,29.908937],[110.515519,29.902502],[110.526952,29.904647],[110.537839,29.896764],[110.535705,29.880351],[110.547631,29.863399],[110.549983,29.848001],[110.575366,29.844835],[110.579907,29.835873],[110.597795,29.840005],[110.606493,29.837],[110.618419,29.826589],[110.62925,29.805119],[110.629688,29.798409],[110.640027,29.782463],[110.641723,29.770435],[110.631821,29.757761],[110.634666,29.749597],[110.652992,29.744656],[110.661088,29.735793],[110.66076,29.719622],[110.672576,29.706835],[110.699327,29.699688],[110.721428,29.687489],[110.731876,29.690283],[110.747686,29.70705],[110.762839,29.715593],[110.764973,29.709897],[110.766559,29.680502],[110.78133,29.683243],[110.814481,29.680556],[110.854415,29.696249],[110.874984,29.684909],[110.890356,29.686898],[110.904689,29.684479],[110.927391,29.676578],[110.927938,29.671633],[110.94249,29.668032],[110.965083,29.677492],[110.98609,29.675933],[110.998562,29.667171],[111.020444,29.669967],[111.032096,29.669053],[111.039208,29.653302],[111.030729,29.645398],[111.049711,29.636957],[111.053322,29.619049],[111.077009,29.619318],[111.110652,29.613779],[111.124383,29.607755],[111.133847,29.608992],[111.148234,29.604743],[111.151298,29.596836],[111.158957,29.59463],[111.173453,29.600547],[111.213278,29.599203],[111.224821,29.60286],[111.252283,29.600547],[111.257316,29.596997],[111.254581,29.587045],[111.267108,29.579782],[111.273782,29.580858],[111.286911,29.555246],[111.294679,29.55686],[111.303213,29.549703],[111.300916,29.5384],[111.319242,29.533341],[111.320445,29.520852],[111.328377,29.511216],[111.337513,29.493448],[111.329417,29.486717],[111.3176,29.464366],[111.32969,29.443681],[111.311255,29.419273],[111.294843,29.412914],[111.291725,29.407848],[111.300697,29.395991],[111.2862,29.389523],[111.26946,29.386558],[111.25923,29.380629],[111.234723,29.33264],[111.245554,29.321044],[111.252009,29.302757],[111.25097,29.29461],[111.234887,29.273513],[111.222141,29.265688],[111.220171,29.25743],[111.232753,29.239888],[111.23144,29.231736],[111.22318,29.223692],[111.20644,29.217537],[111.192928,29.218077],[111.177884,29.223422],[111.165685,29.236163],[111.153869,29.237728],[111.121812,29.218563],[111.092819,29.204146],[111.080783,29.188376],[111.071867,29.16985],[111.043475,29.139271],[111.025805,29.137704],[111.022304,29.120465],[111.00168,29.117925],[110.985324,29.111007],[110.983792,29.118952],[110.974711,29.119222],[110.958464,29.133867],[110.941615,29.138082],[110.945772,29.130949],[110.929744,29.130841],[110.925367,29.118681],[110.913113,29.111331],[110.88959,29.109872],[110.886636,29.100683],[110.876297,29.09771],[110.868693,29.108088],[110.852555,29.09425],[110.852172,29.08679],[110.86098,29.073057],[110.862676,29.064027],[110.873179,29.066406],[110.88215,29.054726],[110.894568,29.049588],[110.909722,29.048723],[110.9147,29.035742],[110.919076,29.022544],[110.943529,29.011778],[110.955291,29.002851],[110.949,28.997007],[110.962019,28.99836],[110.970717,28.992733],[110.98702,28.988404],[110.982588,28.976823],[110.974602,28.976769],[110.965356,28.965186],[110.954908,28.960748],[110.956768,28.951059],[110.950148,28.937308],[110.96284,28.917924],[110.9583,28.906389],[110.972687,28.904223],[110.9897,28.89729],[110.992435,28.888245],[111.002063,28.875732],[111.013114,28.851297],[111.031494,28.838075],[111.040302,28.822683],[111.048453,28.825393],[111.064427,28.823442],[111.072742,28.809837],[111.079361,28.805717],[111.078759,28.793682],[111.086309,28.785387],[111.102228,28.777959],[111.098453,28.770747],[111.115138,28.743358],[111.102556,28.734028],[111.105455,28.727085],[111.09632,28.700499],[111.081166,28.69187],[111.06574,28.696592],[111.051571,28.692088],[111.046648,28.684707],[111.06191,28.668587],[111.064646,28.659739],[111.051681,28.652301],[111.015247,28.649858],[110.995335,28.63786],[110.991724,28.619995],[110.9554,28.61918],[110.946155,28.622004],[110.934722,28.617551],[110.945936,28.601421],[110.943857,28.591644],[110.950696,28.568229],[110.956166,28.568827],[110.978376,28.585505],[110.989262,28.587841],[111.005729,28.583604],[111.010105,28.587352],[111.008026,28.598162],[111.015794,28.599302],[111.020171,28.589742],[111.036691,28.596858],[111.049766,28.608156],[111.057425,28.607938],[111.055346,28.590177],[111.064481,28.582789],[111.054744,28.57062],[111.079306,28.53769],[111.075915,28.53019],[111.067545,28.530135],[111.049274,28.53682],[111.041888,28.535027],[111.029689,28.543668],[111.013168,28.545787],[111.002009,28.537146],[110.993146,28.521765],[110.981658,28.51198],[110.969897,28.512524],[110.959339,28.492245],[110.943803,28.478434],[110.929744,28.484796],[110.923453,28.473268],[110.905345,28.455103],[110.889207,28.447325],[110.88866,28.438948],[110.862129,28.418818],[110.860433,28.406032],[110.88226,28.408099],[110.889481,28.404889],[110.944623,28.42649],[110.96738,28.430353],[110.978704,28.439492],[111.001407,28.440145],[111.007753,28.44553],[111.020116,28.445639],[111.034831,28.454886],[111.050204,28.45891],[111.061692,28.451676],[111.09353,28.456952],[111.096867,28.463642],[111.109339,28.468156],[111.11667,28.464403],[111.126353,28.470549],[111.144952,28.473703],[111.147852,28.487841],[111.154361,28.496541],[111.152173,28.514318],[111.168639,28.517471],[111.175204,28.513883],[111.192217,28.518829],[111.198235,28.526548],[111.215193,28.536222],[111.228651,28.522471],[111.252611,28.531548],[111.281058,28.517905],[111.309176,28.520949],[111.315686,28.524428],[111.324165,28.518829],[111.333793,28.520134],[111.339209,28.527852],[111.34818,28.528722],[111.363388,28.539538],[111.373892,28.551819],[111.383192,28.55057],[111.396594,28.540788],[111.412294,28.547852],[111.431386,28.547418],[111.443367,28.557308],[111.46782,28.556927],[111.491452,28.571652],[111.494187,28.581268],[111.509341,28.585668],[111.518641,28.5955],[111.53921,28.609731],[111.567218,28.638783],[111.574494,28.639326],[111.605402,28.624936],[111.624385,28.618311],[111.636092,28.628466],[111.644954,28.623742],[111.662842,28.624665],[111.663663,28.607884],[111.67351,28.591426],[111.688389,28.589199],[111.702777,28.598976],[111.708904,28.594251],[111.723401,28.609839],[111.719079,28.636448],[111.728269,28.642529],[111.722525,28.645027],[111.730676,28.652193],[111.74211,28.651596],[111.751573,28.657622],[111.759068,28.653442],[111.768258,28.639054],[111.776191,28.634113],[111.787843,28.648718],[111.791344,28.643126],[111.8106,28.640955],[111.81618,28.626403],[111.828488,28.615759],[111.844025,28.616682],[111.850151,28.633353],[111.854747,28.636991],[111.873073,28.630964],[111.888062,28.6371],[111.901191,28.635959],[111.9106,28.643452],[111.918204,28.655396],[111.910163,28.664136],[111.910217,28.671464],[111.923237,28.676946],[111.951519,28.674395],[111.984123,28.663864],[111.979583,28.65621],[111.992001,28.657513],[111.998456,28.646764],[112.014047,28.640737],[112.034616,28.640032],[112.040743,28.65773],[112.025863,28.669292],[112.033412,28.673418],[112.070448,28.672332],[112.07827,28.655124],[112.086531,28.652681],[112.094354,28.641986],[112.107373,28.652301],[112.139759,28.649316],[112.149441,28.656427],[112.142931,28.662236],[112.158796,28.667447],[112.161476,28.675697],[112.169026,28.678303],[112.182757,28.66837],[112.199715,28.674069],[112.207975,28.691002],[112.215306,28.692576],[112.232046,28.707064],[112.231006,28.711839],[112.264923,28.719164],[112.283194,28.728441],[112.283413,28.776874],[112.299606,28.784845],[112.306389,28.800242],[112.304693,28.823009],[112.276466,28.84073],[112.256991,28.861483],[112.258632,28.900811],[112.26175,28.908122],[112.259562,28.922743],[112.257319,28.96773],[112.246871,28.980828],[112.247636,28.997062],[112.254037,29.04975],[112.241455,29.06792],[112.245284,29.100683],[112.235711,29.114412],[112.222855,29.118627],[112.211203,29.117276],[112.208194,29.126356],[112.187735,29.134516],[112.189978,29.145268],[112.201028,29.146025],[112.195776,29.160018],[112.20163,29.179248],[112.223895,29.19907],[112.236422,29.213163],[112.22849,29.216079],[112.22652,29.228443],[112.228763,29.251763],[112.223457,29.266659],[112.222199,29.287327],[112.213446,29.296121],[112.22663,29.294071],[112.234234,29.298657],[112.245284,29.292992],[112.258249,29.29229],[112.263665,29.298711],[112.251192,29.31894],[112.249387,29.328541],[112.252615,29.351946],[112.261696,29.375615],[112.28117,29.395129],[112.284179,29.403483],[112.2943,29.406124],[112.294464,29.428541],[112.300317,29.448206],[112.293534,29.45634],[112.291728,29.478262],[112.283413,29.495225]]]]}},{"type":"Feature","properties":{"adcode":430800,"name":"张家界市","center":[110.479921,29.127401],"centroid":[110.531625,29.390312],"childrenNum":4,"level":"city","parent":{"adcode":430000},"subFeatureIndex":7,"acroutes":[100000,430000]},"geometry":{"type":"MultiPolygon","coordinates":[[[[110.390409,28.881149],[110.400201,28.89572],[110.423123,28.900594],[110.432805,28.890791],[110.449162,28.889816],[110.450913,28.882828],[110.468035,28.880228],[110.472138,28.887487],[110.481766,28.889437],[110.476569,28.898807],[110.4839,28.910776],[110.490191,28.911263],[110.524381,28.886132],[110.530782,28.874107],[110.543966,28.889328],[110.538987,28.908447],[110.521044,28.93276],[110.521919,28.938499],[110.533243,28.946132],[110.551077,28.953278],[110.553539,28.963346],[110.541777,28.982289],[110.558408,28.995438],[110.572576,29.000579],[110.593309,28.969354],[110.620716,28.965186],[110.635979,28.949705],[110.656986,28.935034],[110.666504,28.923501],[110.670498,28.91083],[110.678594,28.906172],[110.690684,28.908122],[110.690903,28.923988],[110.716942,28.913429],[110.730454,28.926154],[110.739371,28.924476],[110.76366,28.905847],[110.775695,28.906172],[110.788879,28.913808],[110.798069,28.935738],[110.798616,28.955227],[110.811417,28.955281],[110.8368,28.941855],[110.849163,28.946511],[110.851844,28.952033],[110.850258,28.968542],[110.839371,28.987754],[110.840465,28.99257],[110.860706,28.998955],[110.889153,28.992462],[110.898452,29.00112],[110.905126,28.995709],[110.915137,29.008532],[110.903102,29.0213],[110.903814,29.034769],[110.9147,29.035742],[110.909722,29.048723],[110.894568,29.049588],[110.88215,29.054726],[110.873179,29.066406],[110.862676,29.064027],[110.86098,29.073057],[110.852172,29.08679],[110.852555,29.09425],[110.868693,29.108088],[110.876297,29.09771],[110.886636,29.100683],[110.88959,29.109872],[110.913113,29.111331],[110.925367,29.118681],[110.929744,29.130841],[110.945772,29.130949],[110.941615,29.138082],[110.958464,29.133867],[110.974711,29.119222],[110.983792,29.118952],[110.985324,29.111007],[111.00168,29.117925],[111.022304,29.120465],[111.025805,29.137704],[111.043475,29.139271],[111.071867,29.16985],[111.080783,29.188376],[111.092819,29.204146],[111.121812,29.218563],[111.153869,29.237728],[111.165685,29.236163],[111.177884,29.223422],[111.192928,29.218077],[111.20644,29.217537],[111.22318,29.223692],[111.23144,29.231736],[111.232753,29.239888],[111.220171,29.25743],[111.222141,29.265688],[111.234887,29.273513],[111.25097,29.29461],[111.252009,29.302757],[111.245554,29.321044],[111.234723,29.33264],[111.25923,29.380629],[111.26946,29.386558],[111.2862,29.389523],[111.300697,29.395991],[111.291725,29.407848],[111.294843,29.412914],[111.311255,29.419273],[111.32969,29.443681],[111.3176,29.464366],[111.329417,29.486717],[111.337513,29.493448],[111.328377,29.511216],[111.320445,29.520852],[111.319242,29.533341],[111.300916,29.5384],[111.303213,29.549703],[111.294679,29.55686],[111.286911,29.555246],[111.273782,29.580858],[111.267108,29.579782],[111.254581,29.587045],[111.257316,29.596997],[111.252283,29.600547],[111.224821,29.60286],[111.213278,29.599203],[111.173453,29.600547],[111.158957,29.59463],[111.151298,29.596836],[111.148234,29.604743],[111.133847,29.608992],[111.124383,29.607755],[111.110652,29.613779],[111.077009,29.619318],[111.053322,29.619049],[111.049711,29.636957],[111.030729,29.645398],[111.039208,29.653302],[111.032096,29.669053],[111.020444,29.669967],[110.998562,29.667171],[110.98609,29.675933],[110.965083,29.677492],[110.94249,29.668032],[110.927938,29.671633],[110.927391,29.676578],[110.904689,29.684479],[110.890356,29.686898],[110.874984,29.684909],[110.854415,29.696249],[110.814481,29.680556],[110.78133,29.683243],[110.766559,29.680502],[110.764973,29.709897],[110.762839,29.715593],[110.747686,29.70705],[110.731876,29.690283],[110.721428,29.687489],[110.699327,29.699688],[110.672576,29.706835],[110.66076,29.719622],[110.661088,29.735793],[110.652992,29.744656],[110.634666,29.749597],[110.631821,29.757761],[110.62378,29.755935],[110.614425,29.747127],[110.602062,29.742024],[110.574545,29.723437],[110.562839,29.712584],[110.525256,29.693508],[110.507095,29.692111],[110.493856,29.700978],[110.465191,29.713068],[110.449381,29.690821],[110.447029,29.664645],[110.416175,29.661742],[110.413878,29.654646],[110.372575,29.633515],[110.355836,29.638839],[110.353101,29.653839],[110.339479,29.668139],[110.321262,29.665021],[110.315682,29.661151],[110.299873,29.662387],[110.29205,29.671848],[110.289917,29.69641],[110.27821,29.709091],[110.260376,29.719515],[110.24577,29.732247],[110.219894,29.746643],[110.188166,29.754485],[110.160813,29.753787],[110.144894,29.771133],[110.131054,29.781067],[110.113494,29.789658],[110.06415,29.782839],[110.024161,29.76963],[109.990846,29.772207],[109.976021,29.768126],[109.969729,29.771777],[109.949708,29.772959],[109.947136,29.778865],[109.940298,29.77414],[109.907913,29.764206],[109.896863,29.770435],[109.888438,29.76587],[109.869784,29.774677],[109.836633,29.769844],[109.820878,29.769898],[109.791884,29.7634],[109.771862,29.75137],[109.769291,29.744495],[109.755943,29.743259],[109.753536,29.734128],[109.76858,29.727842],[109.771589,29.720966],[109.76021,29.71339],[109.766173,29.702912],[109.760101,29.689101],[109.73707,29.678406],[109.714969,29.673353],[109.718416,29.658624],[109.71579,29.649485],[109.701238,29.636312],[109.710866,29.629644],[109.715571,29.613133],[109.72695,29.607863],[109.745713,29.615339],[109.761687,29.615177],[109.769565,29.606518],[109.764915,29.596136],[109.768525,29.587314],[109.782366,29.576608],[109.760101,29.561649],[109.74916,29.549487],[109.738766,29.547604],[109.734663,29.540984],[109.740954,29.534256],[109.752934,29.509062],[109.76579,29.500017],[109.769455,29.491779],[109.778755,29.486878],[109.779357,29.478046],[109.788383,29.463935],[109.801895,29.448852],[109.808241,29.427086],[109.795276,29.417117],[109.79451,29.411675],[109.821206,29.388661],[109.828919,29.373297],[109.908405,29.441741],[109.925637,29.444435],[109.935867,29.434414],[109.945276,29.398417],[109.952662,29.383486],[109.945167,29.369901],[109.954795,29.358147],[109.960375,29.341269],[109.952935,29.333827],[109.936141,29.325143],[109.951294,29.318077],[109.975528,29.299142],[110.001568,29.29542],[110.016338,29.288298],[110.049216,29.314571],[110.068417,29.323795],[110.097192,29.308853],[110.112564,29.289701],[110.113548,29.279017],[110.103537,29.253436],[110.082859,29.251223],[110.080616,29.2326],[110.073176,29.225636],[110.070058,29.211867],[110.084828,29.184434],[110.090518,29.167311],[110.089041,29.151266],[110.099872,29.139595],[110.119128,29.141216],[110.128428,29.136407],[110.140408,29.14543],[110.158187,29.165204],[110.164861,29.165528],[110.179085,29.153967],[110.189643,29.162827],[110.203921,29.161044],[110.205562,29.151968],[110.215901,29.136083],[110.223997,29.136461],[110.216722,29.129112],[110.238986,29.122248],[110.261634,29.1196],[110.264041,29.110142],[110.250529,29.093655],[110.249654,29.076896],[110.261962,29.069542],[110.273505,29.074409],[110.284446,29.085438],[110.304194,29.091331],[110.299599,29.057159],[110.305289,29.038609],[110.313987,29.035905],[110.323122,29.041746],[110.340354,29.041313],[110.341613,29.02725],[110.347357,29.019406],[110.346208,29.011129],[110.327991,28.983858],[110.33193,28.981315],[110.318965,28.973143],[110.319184,28.967297],[110.306492,28.958258],[110.308133,28.944292],[110.314588,28.938336],[110.331,28.941152],[110.361087,28.927454],[110.364807,28.907959],[110.358735,28.891224],[110.384665,28.885428],[110.390409,28.881149]]]]}},{"type":"Feature","properties":{"adcode":430900,"name":"益阳市","center":[112.355042,28.570066],"centroid":[111.958046,28.573867],"childrenNum":6,"level":"city","parent":{"adcode":430000},"subFeatureIndex":8,"acroutes":[100000,430000]},"geometry":{"type":"MultiPolygon","coordinates":[[[[112.685384,28.525407],[112.688283,28.54432],[112.701741,28.552417],[112.726522,28.557199],[112.736095,28.568229],[112.726194,28.581702],[112.716456,28.579203],[112.713229,28.587189],[112.717496,28.596206],[112.705351,28.599574],[112.684016,28.596369],[112.675154,28.581214],[112.668371,28.584256],[112.658688,28.580507],[112.648841,28.564263],[112.635439,28.559046],[112.629366,28.5472],[112.609727,28.540788],[112.591948,28.542962],[112.582539,28.556873],[112.562462,28.563556],[112.563721,28.570946],[112.574388,28.585125],[112.582813,28.590123],[112.590143,28.601692],[112.585001,28.620918],[112.588721,28.62738],[112.580515,28.629715],[112.57406,28.623796],[112.563666,28.629389],[112.552561,28.644104],[112.544136,28.639434],[112.533797,28.640412],[112.510602,28.654799],[112.521106,28.665493],[112.525318,28.678357],[112.526412,28.702561],[112.534563,28.70956],[112.548239,28.712328],[112.555843,28.719652],[112.552233,28.72958],[112.569082,28.731641],[112.58057,28.73967],[112.603764,28.746884],[112.606117,28.758002],[112.617495,28.770042],[112.619137,28.778555],[112.641784,28.789453],[112.671708,28.791568],[112.672966,28.811517],[112.664924,28.821057],[112.659837,28.840839],[112.668371,28.85043],[112.677452,28.871235],[112.685165,28.879741],[112.722911,28.883478],[112.773185,28.90276],[112.784181,28.911967],[112.797474,28.9137],[112.811588,28.921552],[112.83812,28.929295],[112.847967,28.935521],[112.87242,28.962967],[112.876085,28.984075],[112.891402,28.999388],[112.927945,29.023031],[112.9344,29.037311],[112.949389,29.060783],[112.93905,29.065541],[112.937737,29.078139],[112.92707,29.109061],[112.924663,29.149429],[112.901085,29.154615],[112.88161,29.162773],[112.812901,29.1524],[112.798513,29.159802],[112.813448,29.178654],[112.810384,29.185514],[112.793864,29.190915],[112.775592,29.176602],[112.75661,29.169958],[112.741949,29.168283],[112.724553,29.177628],[112.715855,29.18735],[112.711259,29.185352],[112.693207,29.192589],[112.68243,29.192265],[112.677561,29.205388],[112.680953,29.214027],[112.676358,29.224718],[112.681664,29.230441],[112.679093,29.2448],[112.693699,29.253976],[112.682813,29.269573],[112.683305,29.27497],[112.699881,29.287381],[112.689268,29.295743],[112.680789,29.294988],[112.673622,29.306264],[112.66476,29.300383],[112.652561,29.321421],[112.634454,29.335984],[112.611806,29.333287],[112.590417,29.317861],[112.579421,29.303674],[112.560219,29.304591],[112.547364,29.301786],[112.532429,29.308907],[112.502068,29.312198],[112.496981,29.317052],[112.490963,29.337602],[112.485766,29.342941],[112.464267,29.35351],[112.439924,29.360627],[112.423075,29.371734],[112.392057,29.396476],[112.386641,29.406016],[112.388829,29.420997],[112.386149,29.426871],[112.366783,29.442549],[112.366182,29.458441],[112.350974,29.453108],[112.342002,29.444435],[112.328271,29.450091],[112.324442,29.480416],[112.331116,29.51057],[112.320066,29.516007],[112.315744,29.524298],[112.297691,29.516815],[112.290744,29.516923],[112.283413,29.495225],[112.291728,29.478262],[112.293534,29.45634],[112.300317,29.448206],[112.294464,29.428541],[112.2943,29.406124],[112.284179,29.403483],[112.28117,29.395129],[112.261696,29.375615],[112.252615,29.351946],[112.249387,29.328541],[112.251192,29.31894],[112.263665,29.298711],[112.258249,29.29229],[112.245284,29.292992],[112.234234,29.298657],[112.22663,29.294071],[112.213446,29.296121],[112.222199,29.287327],[112.223457,29.266659],[112.228763,29.251763],[112.22652,29.228443],[112.22849,29.216079],[112.236422,29.213163],[112.223895,29.19907],[112.20163,29.179248],[112.195776,29.160018],[112.201028,29.146025],[112.189978,29.145268],[112.187735,29.134516],[112.208194,29.126356],[112.211203,29.117276],[112.222855,29.118627],[112.235711,29.114412],[112.245284,29.100683],[112.241455,29.06792],[112.254037,29.04975],[112.247636,28.997062],[112.246871,28.980828],[112.257319,28.96773],[112.259562,28.922743],[112.26175,28.908122],[112.258632,28.900811],[112.256991,28.861483],[112.276466,28.84073],[112.304693,28.823009],[112.306389,28.800242],[112.299606,28.784845],[112.283413,28.776874],[112.283194,28.728441],[112.264923,28.719164],[112.231006,28.711839],[112.232046,28.707064],[112.215306,28.692576],[112.207975,28.691002],[112.199715,28.674069],[112.182757,28.66837],[112.169026,28.678303],[112.161476,28.675697],[112.158796,28.667447],[112.142931,28.662236],[112.149441,28.656427],[112.139759,28.649316],[112.107373,28.652301],[112.094354,28.641986],[112.086531,28.652681],[112.07827,28.655124],[112.070448,28.672332],[112.033412,28.673418],[112.025863,28.669292],[112.040743,28.65773],[112.034616,28.640032],[112.014047,28.640737],[111.998456,28.646764],[111.992001,28.657513],[111.979583,28.65621],[111.984123,28.663864],[111.951519,28.674395],[111.923237,28.676946],[111.910217,28.671464],[111.910163,28.664136],[111.918204,28.655396],[111.9106,28.643452],[111.901191,28.635959],[111.888062,28.6371],[111.873073,28.630964],[111.854747,28.636991],[111.850151,28.633353],[111.844025,28.616682],[111.828488,28.615759],[111.81618,28.626403],[111.8106,28.640955],[111.791344,28.643126],[111.787843,28.648718],[111.776191,28.634113],[111.768258,28.639054],[111.759068,28.653442],[111.751573,28.657622],[111.74211,28.651596],[111.730676,28.652193],[111.722525,28.645027],[111.728269,28.642529],[111.719079,28.636448],[111.723401,28.609839],[111.708904,28.594251],[111.702777,28.598976],[111.688389,28.589199],[111.67351,28.591426],[111.663663,28.607884],[111.662842,28.624665],[111.644954,28.623742],[111.636092,28.628466],[111.624385,28.618311],[111.605402,28.624936],[111.574494,28.639326],[111.567218,28.638783],[111.53921,28.609731],[111.518641,28.5955],[111.509341,28.585668],[111.494187,28.581268],[111.491452,28.571652],[111.46782,28.556927],[111.443367,28.557308],[111.431386,28.547418],[111.412294,28.547852],[111.396594,28.540788],[111.383192,28.55057],[111.373892,28.551819],[111.363388,28.539538],[111.34818,28.528722],[111.339209,28.527852],[111.333793,28.520134],[111.324165,28.518829],[111.315686,28.524428],[111.309176,28.520949],[111.281058,28.517905],[111.252611,28.531548],[111.228651,28.522471],[111.215193,28.536222],[111.198235,28.526548],[111.192217,28.518829],[111.175204,28.513883],[111.168639,28.517471],[111.152173,28.514318],[111.154361,28.496541],[111.147852,28.487841],[111.144952,28.473703],[111.126353,28.470549],[111.11667,28.464403],[111.109339,28.468156],[111.096867,28.463642],[111.09353,28.456952],[111.061692,28.451676],[111.050204,28.45891],[111.034831,28.454886],[111.020116,28.445639],[111.007753,28.44553],[111.001407,28.440145],[110.978704,28.439492],[110.96738,28.430353],[110.944623,28.42649],[110.889481,28.404889],[110.88226,28.408099],[110.860433,28.406032],[110.853923,28.398468],[110.83587,28.393896],[110.832752,28.380508],[110.825914,28.37169],[110.793966,28.354379],[110.753266,28.338698],[110.741067,28.325466],[110.733189,28.311361],[110.7211,28.300794],[110.739535,28.281619],[110.74971,28.280911],[110.774601,28.27312],[110.783354,28.278241],[110.793036,28.275898],[110.802719,28.264348],[110.806275,28.253013],[110.787839,28.231268],[110.79982,28.223201],[110.804579,28.213225],[110.824601,28.203794],[110.826789,28.209082],[110.840082,28.214643],[110.848069,28.213007],[110.84889,28.204721],[110.858518,28.205157],[110.860487,28.198614],[110.853266,28.188418],[110.849163,28.172277],[110.818638,28.13966],[110.833026,28.118874],[110.844349,28.116364],[110.823452,28.087441],[110.83319,28.087496],[110.858846,28.076361],[110.876352,28.081819],[110.896155,28.058784],[110.884065,28.050977],[110.86645,28.025477],[110.866177,28.013735],[110.878157,28.01308],[110.88959,28.000954],[110.907698,27.998223],[110.92203,28.000626],[110.92575,28.021326],[110.938059,28.018486],[110.942982,28.038364],[110.955728,28.050758],[110.953485,28.057091],[110.962676,28.058129],[110.970936,28.065826],[110.971319,28.054798],[110.992162,28.054034],[111.010488,28.044534],[111.022031,28.041531],[111.013223,28.028917],[111.022031,28.027497],[111.03505,28.033723],[111.04156,28.022309],[111.063223,28.007236],[111.070608,27.995273],[111.081987,27.995601],[111.097906,28.006799],[111.093803,28.02717],[111.118475,28.050158],[111.114208,28.064134],[111.123289,28.068774],[111.137895,28.085968],[111.140959,28.103431],[111.151571,28.122966],[111.160926,28.122857],[111.189537,28.154988],[111.186528,28.160606],[111.216014,28.159297],[111.225149,28.161479],[111.235653,28.154115],[111.257753,28.167532],[111.279034,28.191036],[111.285215,28.214806],[111.296047,28.225436],[111.314373,28.234211],[111.32597,28.226526],[111.337732,28.20592],[111.332097,28.195943],[111.341835,28.193162],[111.352064,28.199051],[111.382918,28.196324],[111.386911,28.17893],[111.398016,28.180021],[111.434833,28.208101],[111.448454,28.202867],[111.445336,28.189509],[111.450095,28.187382],[111.477448,28.199323],[111.483137,28.204176],[111.495719,28.189945],[111.485763,28.159515],[111.49096,28.153024],[111.481387,28.138351],[111.482645,28.120402],[111.499877,28.101412],[111.500424,28.092626],[111.510982,28.090279],[111.493312,28.074887],[111.49189,28.066863],[111.494789,28.037873],[111.501956,28.04164],[111.517875,28.030992],[111.524439,28.031211],[111.522032,28.044479],[111.506879,28.053324],[111.514702,28.06528],[111.527886,28.049393],[111.534013,28.054143],[111.543914,28.047537],[111.540687,28.035579],[111.543859,28.020398],[111.567547,28.032903],[111.575807,28.018869],[111.564264,28.018104],[111.551409,27.991886],[111.542054,27.994126],[111.529527,27.986587],[111.55026,27.974841],[111.583794,27.994454],[111.592766,28.006471],[111.599768,28.009693],[111.588991,28.018596],[111.589811,28.027115],[111.601682,28.034542],[111.621704,28.016083],[111.634286,28.015319],[111.651518,28.026241],[111.662788,28.024712],[111.651573,28.021163],[111.652284,28.015756],[111.662952,28.014227],[111.672853,28.036453],[111.68549,28.040493],[111.683466,28.0145],[111.691289,28.009912],[111.684888,28.002975],[111.688499,27.99063],[111.697689,27.994181],[111.706114,27.99063],[111.71514,27.993361],[111.726792,27.983474],[111.743368,27.994235],[111.747963,28.003904],[111.765633,28.006143],[111.773893,28.010676],[111.779418,28.007072],[111.778871,27.996639],[111.793094,27.989701],[111.796103,28.00516],[111.823401,28.022582],[111.838335,28.019961],[111.848346,28.028644],[111.858193,28.030938],[111.870173,28.026678],[111.891837,28.026951],[111.902613,28.021982],[111.913117,28.027989],[111.907537,28.041804],[111.911038,28.052287],[111.926246,28.065498],[111.914101,28.079363],[111.91525,28.082802],[111.899167,28.09983],[111.90885,28.116036],[111.93188,28.133332],[111.933248,28.168132],[111.941782,28.172277],[111.944736,28.186728],[111.961147,28.198124],[111.962132,28.208864],[111.986585,28.224182],[112.003489,28.224509],[112.003981,28.235029],[112.009671,28.244021],[112.033139,28.252468],[112.051684,28.25127],[112.080677,28.260806],[112.082264,28.267889],[112.093424,28.265001],[112.099058,28.270069],[112.11629,28.271703],[112.123128,28.266146],[112.137297,28.266636],[112.146214,28.254539],[112.169518,28.245602],[112.177997,28.235737],[112.195503,28.23323],[112.210109,28.239225],[112.223293,28.233939],[112.227286,28.221239],[112.237954,28.210445],[112.251685,28.2244],[112.255733,28.233448],[112.264431,28.235683],[112.280678,28.252632],[112.288282,28.254049],[112.294135,28.247073],[112.306444,28.261351],[112.322473,28.263258],[112.316674,28.282981],[112.332921,28.284397],[112.346761,28.274809],[112.356937,28.277369],[112.358632,28.283471],[112.349168,28.281837],[112.345284,28.289518],[112.352779,28.291261],[112.370339,28.284397],[112.377998,28.290063],[112.393753,28.290281],[112.404803,28.29867],[112.408468,28.294366],[112.422692,28.305587],[112.420066,28.312559],[112.429311,28.311143],[112.432976,28.317896],[112.438337,28.310652],[112.451248,28.317842],[112.466018,28.312886],[112.472965,28.317733],[112.486915,28.309236],[112.500974,28.311905],[112.505296,28.320728],[112.525974,28.325956],[112.534563,28.332],[112.535766,28.325466],[112.553928,28.318931],[112.560493,28.325411],[112.571379,28.324976],[112.564432,28.333144],[112.562462,28.344742],[112.575209,28.354596],[112.575427,28.369077],[112.580351,28.372887],[112.578436,28.382358],[112.584235,28.40244],[112.594355,28.40761],[112.594793,28.414629],[112.612134,28.424531],[112.624279,28.446074],[112.627288,28.468265],[112.639815,28.469352],[112.654421,28.484524],[112.651741,28.495671],[112.663229,28.501053],[112.672583,28.517525],[112.685384,28.525407]]]]}},{"type":"Feature","properties":{"adcode":431000,"name":"郴州市","center":[113.032067,25.793589],"centroid":[113.142071,25.813202],"childrenNum":11,"level":"city","parent":{"adcode":430000},"subFeatureIndex":9,"acroutes":[100000,430000]},"geometry":{"type":"MultiPolygon","coordinates":[[[[112.364212,25.191725],[112.373731,25.177561],[112.393151,25.160148],[112.387407,25.152196],[112.399497,25.14066],[112.413337,25.141332],[112.426138,25.156284],[112.430077,25.17409],[112.442987,25.185623],[112.454858,25.17353],[112.45267,25.159868],[112.45825,25.152084],[112.477451,25.151413],[112.491018,25.144468],[112.502615,25.144636],[112.507703,25.13674],[112.537025,25.13422],[112.562681,25.12453],[112.596543,25.126266],[112.612736,25.133212],[112.624826,25.134108],[112.628218,25.140604],[112.648021,25.133604],[112.659782,25.132764],[112.669848,25.113047],[112.679749,25.10991],[112.695231,25.095513],[112.697255,25.089966],[112.715636,25.078368],[112.719192,25.048219],[112.715143,25.026023],[112.724881,25.010831],[112.741839,24.998609],[112.745505,24.981675],[112.742168,24.977469],[112.743152,24.960308],[112.750537,24.955372],[112.773459,24.949987],[112.784673,24.936637],[112.782211,24.922724],[112.786697,24.912401],[112.780734,24.897307],[112.788284,24.892369],[112.80382,24.890517],[112.843973,24.897363],[112.873514,24.89669],[112.877835,24.905668],[112.904367,24.921827],[112.924553,24.918853],[112.937354,24.92048],[112.941785,24.915936],[112.959236,24.923454],[112.966785,24.919302],[112.983634,24.920929],[112.994794,24.927381],[112.991676,24.938488],[113.011917,24.946117],[113.002781,24.957111],[113.00847,24.961934],[113.010002,24.977357],[113.002289,24.990871],[112.990527,24.995413],[112.992059,25.017951],[112.978437,25.026472],[112.979422,25.033927],[113.002289,25.057971],[113.002015,25.07114],[113.018427,25.083131],[113.004532,25.089182],[112.999608,25.103076],[112.991129,25.109462],[112.981939,25.125258],[112.967989,25.141612],[112.974335,25.168267],[112.991567,25.176777],[113.00858,25.190101],[113.030516,25.194468],[113.034455,25.201409],[113.029751,25.210533],[113.01777,25.211149],[112.999006,25.244055],[112.979915,25.245062],[112.972912,25.251161],[112.959564,25.254071],[112.951851,25.245734],[112.934072,25.250378],[112.933361,25.24316],[112.924006,25.248643],[112.896927,25.239299],[112.89173,25.246181],[112.868317,25.248811],[112.86591,25.259778],[112.873951,25.274324],[112.866457,25.276561],[112.856391,25.291609],[112.854914,25.311855],[112.858798,25.320243],[112.851796,25.33344],[112.857376,25.336851],[112.8687,25.327849],[112.877671,25.33372],[112.894849,25.337578],[112.900593,25.311352],[112.913175,25.299887],[112.927836,25.299887],[112.931829,25.322816],[112.945068,25.326339],[112.95114,25.337466],[112.964707,25.342163],[112.968098,25.349822],[112.987956,25.353791],[112.995396,25.348983],[113.009236,25.352897],[113.023678,25.345964],[113.029751,25.361227],[113.041622,25.366034],[113.064598,25.381797],[113.080134,25.383362],[113.080626,25.390963],[113.088777,25.396552],[113.090418,25.406778],[113.096873,25.410746],[113.092388,25.417507],[113.114379,25.42058],[113.128383,25.413204],[113.130736,25.427117],[113.118427,25.447285],[113.127946,25.449687],[113.122366,25.45572],[113.13462,25.467673],[113.149992,25.468008],[113.152016,25.492246],[113.169357,25.488058],[113.177071,25.471583],[113.200812,25.479402],[113.210659,25.496713],[113.226195,25.509667],[113.243263,25.515641],[113.249062,25.514078],[113.260824,25.499449],[113.269412,25.505256],[113.282596,25.4942],[113.291786,25.500901],[113.291732,25.516367],[113.303329,25.515864],[113.296819,25.508383],[113.311371,25.490459],[113.309183,25.481021],[113.315966,25.467506],[113.313942,25.442928],[113.329752,25.450804],[113.340091,25.449911],[113.352782,25.436838],[113.35973,25.438403],[113.366951,25.431196],[113.371874,25.406834],[113.376524,25.400743],[113.38938,25.403649],[113.393592,25.397558],[113.407049,25.401414],[113.424117,25.392695],[113.427728,25.373245],[113.442279,25.361283],[113.449829,25.35955],[113.462411,25.369835],[113.470179,25.365643],[113.480026,25.375201],[113.50415,25.374978],[113.519194,25.370059],[113.515091,25.360668],[113.524336,25.353624],[113.536098,25.368494],[113.544304,25.366593],[113.554533,25.351835],[113.581448,25.342722],[113.583308,25.331875],[113.579807,25.316609],[113.585989,25.307325],[113.61077,25.32701],[113.620507,25.325668],[113.628823,25.330141],[113.658035,25.329246],[113.663998,25.337746],[113.68019,25.334503],[113.687138,25.352058],[113.707926,25.352617],[113.706558,25.360891],[113.725267,25.358599],[113.734512,25.348872],[113.743976,25.363966],[113.754097,25.361171],[113.758418,25.343784],[113.764162,25.333608],[113.75809,25.329973],[113.780191,25.334055],[113.800486,25.32947],[113.821274,25.330756],[113.832817,25.343896],[113.833418,25.353959],[113.839764,25.363463],[113.860935,25.369332],[113.876909,25.380344],[113.883254,25.395322],[113.881777,25.406946],[113.892062,25.411863],[113.884458,25.420301],[113.886865,25.436615],[113.913397,25.442816],[113.943484,25.43885],[113.939929,25.459407],[113.951417,25.470857],[113.958966,25.483646],[113.952073,25.486941],[113.955629,25.496657],[113.945837,25.499561],[113.953277,25.505033],[113.96285,25.528258],[113.986099,25.528984],[113.984075,25.538585],[113.992391,25.565152],[113.97948,25.573244],[113.983091,25.599357],[113.978441,25.605606],[113.957106,25.61191],[113.949557,25.625186],[113.951253,25.637569],[113.943266,25.6427],[113.937576,25.662664],[113.932926,25.663445],[113.926635,25.685468],[113.913834,25.703753],[113.918266,25.71741],[113.914272,25.728668],[113.918922,25.739479],[113.937358,25.756196],[113.946876,25.761322],[113.961701,25.777311],[113.960662,25.796863],[113.971329,25.814741],[113.970071,25.833953],[113.977292,25.839855],[113.991351,25.860565],[114.010279,25.871086],[114.013944,25.885614],[114.028277,25.89335],[114.022533,25.906817],[114.021822,25.919226],[114.03145,25.938921],[114.021111,25.95561],[114.021056,25.975243],[114.028222,25.981361],[114.027128,25.991037],[114.017609,25.992928],[114.009075,26.00416],[114.008474,26.015669],[114.028113,26.031179],[114.036592,26.046798],[114.035224,26.059025],[114.045837,26.070695],[114.043813,26.076697],[114.069852,26.078531],[114.085607,26.066361],[114.10005,26.071807],[114.106888,26.069473],[114.120181,26.084198],[114.118977,26.089865],[114.107489,26.095144],[114.108748,26.10031],[114.156724,26.115809],[114.171056,26.123253],[114.187687,26.120975],[114.214984,26.137471],[114.225323,26.14769],[114.237249,26.152188],[114.235717,26.160073],[114.225378,26.159684],[114.218485,26.168513],[114.232216,26.17995],[114.222096,26.188888],[114.21679,26.203154],[114.192282,26.196715],[114.183748,26.201045],[114.181286,26.214477],[114.148846,26.203265],[114.141953,26.203376],[114.102785,26.187833],[114.100378,26.178395],[114.088562,26.168402],[114.074667,26.171789],[114.05913,26.166181],[114.055356,26.181338],[114.040968,26.177396],[114.036373,26.188555],[114.027894,26.180061],[114.013397,26.184058],[113.992117,26.167791],[113.985443,26.166403],[113.97215,26.154742],[113.962686,26.150855],[113.944524,26.163738],[113.9518,26.177896],[113.94611,26.184502],[113.930246,26.172788],[113.916953,26.171344],[113.914491,26.15874],[113.902839,26.148023],[113.896438,26.135527],[113.888451,26.130362],[113.860278,26.119309],[113.849611,26.107588],[113.845071,26.095699],[113.824775,26.084087],[113.811099,26.086421],[113.805793,26.100033],[113.791624,26.10431],[113.780792,26.093699],[113.780957,26.066139],[113.761536,26.04791],[113.750705,26.041629],[113.736427,26.041129],[113.709074,26.065805],[113.693265,26.09581],[113.702455,26.124419],[113.72204,26.133139],[113.729261,26.139248],[113.736536,26.159351],[113.738724,26.18317],[113.725158,26.223745],[113.708473,26.234067],[113.67833,26.247273],[113.671602,26.256761],[113.655464,26.270575],[113.64414,26.267968],[113.615201,26.278896],[113.617061,26.308236],[113.60705,26.315113],[113.598954,26.326646],[113.597149,26.34583],[113.592499,26.360187],[113.583527,26.370331],[113.583199,26.394661],[113.607707,26.419096],[113.609621,26.431007],[113.603275,26.448345],[113.588998,26.467121],[113.595671,26.479913],[113.603604,26.507652],[113.589162,26.511416],[113.587028,26.520882],[113.572969,26.519111],[113.558691,26.549497],[113.562192,26.575172],[113.554971,26.585352],[113.541295,26.59271],[113.523461,26.595476],[113.509183,26.59271],[113.495781,26.58419],[113.491021,26.575338],[113.477072,26.562667],[113.467279,26.559347],[113.458144,26.561782],[113.429478,26.558738],[113.414599,26.587399],[113.399117,26.596969],[113.400266,26.605211],[113.411371,26.610134],[113.418045,26.629381],[113.415474,26.645694],[113.400977,26.658245],[113.399883,26.666593],[113.392224,26.674885],[113.381448,26.6939],[113.382049,26.69915],[113.400758,26.706943],[113.413286,26.72982],[113.427618,26.764569],[113.428111,26.769761],[113.412684,26.782575],[113.404697,26.797596],[113.394303,26.804774],[113.384456,26.797099],[113.363669,26.800081],[113.338121,26.81024],[113.326305,26.80759],[113.315091,26.79616],[113.306283,26.773517],[113.299281,26.768104],[113.283417,26.771473],[113.27811,26.777715],[113.285441,26.79003],[113.285331,26.799694],[113.273789,26.813056],[113.280627,26.825202],[113.259784,26.827797],[113.258526,26.815486],[113.238066,26.805216],[113.224609,26.814437],[113.223679,26.820896],[113.206338,26.825478],[113.207103,26.829674],[113.183854,26.825202],[113.160495,26.827521],[113.153165,26.837568],[113.144138,26.834477],[113.142935,26.812504],[113.149062,26.792129],[113.097256,26.781636],[113.09556,26.759929],[113.101961,26.753245],[113.113066,26.753024],[113.115364,26.74413],[113.12904,26.74413],[113.131392,26.738053],[113.121381,26.73098],[113.122311,26.72319],[113.13916,26.71794],[113.134784,26.71258],[113.152289,26.700532],[113.160878,26.687875],[113.182979,26.687765],[113.188176,26.662447],[113.179587,26.638339],[113.186699,26.608088],[113.179259,26.578492],[113.179149,26.564438],[113.159182,26.541638],[113.160003,26.534222],[113.171655,26.521214],[113.179423,26.519388],[113.189653,26.506157],[113.214324,26.502448],[113.230079,26.482072],[113.226852,26.467065],[113.217388,26.462746],[113.210112,26.465182],[113.194904,26.451669],[113.192278,26.44552],[113.211699,26.433112],[113.212191,26.425246],[113.191239,26.406186],[113.179095,26.404967],[113.171874,26.412115],[113.163558,26.409566],[113.16044,26.387733],[113.167114,26.374266],[113.156556,26.36246],[113.168865,26.3491],[113.164762,26.344499],[113.173788,26.329696],[113.162683,26.324317],[113.142059,26.32587],[113.127344,26.31356],[113.130626,26.306572],[113.128821,26.29304],[113.119193,26.29304],[113.117059,26.287327],[113.103547,26.290544],[113.087136,26.273626],[113.091676,26.250103],[113.073514,26.24855],[113.068153,26.252933],[113.05207,26.248494],[113.045287,26.254542],[113.032103,26.25199],[113.025867,26.245276],[113.039926,26.213589],[113.034948,26.206651],[113.035659,26.172843],[113.008635,26.155631],[112.992989,26.162349],[112.984564,26.156575],[112.968645,26.154242],[112.949882,26.160184],[112.942606,26.170789],[112.930133,26.176785],[112.921052,26.174398],[112.920997,26.157963],[112.903601,26.148467],[112.891074,26.156519],[112.875866,26.1498],[112.870067,26.155797],[112.857923,26.154187],[112.846435,26.158296],[112.838557,26.155742],[112.818754,26.161794],[112.818535,26.186667],[112.809728,26.192163],[112.802616,26.19022],[112.795614,26.180116],[112.78987,26.179839],[112.79173,26.193218],[112.786041,26.196993],[112.775975,26.183892],[112.777179,26.177341],[112.78812,26.175342],[112.791402,26.166292],[112.783634,26.164237],[112.782157,26.146024],[112.768371,26.145524],[112.758743,26.149855],[112.760384,26.133084],[112.752507,26.129862],[112.746216,26.143802],[112.739979,26.144469],[112.735056,26.134583],[112.720395,26.125474],[112.710275,26.131751],[112.707704,26.122419],[112.688557,26.114198],[112.686423,26.123808],[112.676139,26.125974],[112.673787,26.111032],[112.665307,26.10981],[112.654913,26.101033],[112.642277,26.105977],[112.646161,26.112421],[112.658196,26.114976],[112.670668,26.127696],[112.654257,26.129251],[112.637299,26.138915],[112.630132,26.154409],[112.633688,26.163293],[112.623403,26.192108],[112.608961,26.198436],[112.602834,26.217085],[112.597802,26.220526],[112.581062,26.219083],[112.58057,26.208982],[112.572309,26.193384],[112.577451,26.182004],[112.576248,26.168346],[112.582047,26.15924],[112.578381,26.153632],[112.566565,26.158518],[112.554804,26.147245],[112.529092,26.147579],[112.524443,26.137471],[112.5129,26.135583],[112.50825,26.143858],[112.507812,26.159573],[112.48872,26.150911],[112.482046,26.160739],[112.485055,26.167957],[112.47953,26.175786],[112.450919,26.180394],[112.444574,26.175953],[112.429256,26.189721],[112.405788,26.184835],[112.395066,26.186168],[112.386641,26.205208],[112.377287,26.201544],[112.375044,26.190553],[112.364322,26.181282],[112.357046,26.161294],[112.33779,26.167569],[112.327068,26.161128],[112.310437,26.158574],[112.31186,26.148967],[112.304256,26.132917],[112.292385,26.134417],[112.290689,26.144024],[112.284453,26.143636],[112.266947,26.13114],[112.258523,26.130751],[112.257702,26.123308],[112.232428,26.117865],[112.230295,26.107032],[112.240579,26.09331],[112.251685,26.089588],[112.26186,26.092866],[112.271159,26.089032],[112.282593,26.101699],[112.291619,26.099977],[112.299715,26.090365],[112.309836,26.099033],[112.321816,26.093755],[112.33582,26.076641],[112.328545,26.039072],[112.306444,26.00694],[112.300426,25.978747],[112.292987,25.974298],[112.311532,25.962396],[112.299332,25.962507],[112.304475,25.953997],[112.309836,25.95611],[112.316783,25.944039],[112.315197,25.935806],[112.296816,25.931466],[112.265525,25.896689],[112.272089,25.886337],[112.288665,25.886282],[112.312407,25.890567],[112.33686,25.885725],[112.349715,25.906595],[112.360383,25.905871],[112.359562,25.894407],[112.377998,25.859285],[112.38686,25.859786],[112.387024,25.846258],[112.380514,25.837293],[112.359289,25.834398],[112.357101,25.818249],[112.361696,25.809116],[112.377068,25.803658],[112.385383,25.805552],[112.38686,25.789343],[112.377013,25.760486],[112.37756,25.750791],[112.392057,25.740315],[112.383523,25.730618],[112.361805,25.720196],[112.352068,25.712393],[112.343315,25.694277],[112.336422,25.690876],[112.321433,25.698458],[112.317002,25.723262],[112.310602,25.728891],[112.297363,25.730284],[112.278107,25.711167],[112.247363,25.703921],[112.243041,25.684855],[112.245612,25.672087],[112.257921,25.650452],[112.257429,25.634055],[112.238829,25.603876],[112.243643,25.589928],[112.260492,25.58234],[112.257702,25.573021],[112.246269,25.567608],[112.250973,25.559013],[112.270284,25.554883],[112.285766,25.555776],[112.312844,25.535013],[112.325591,25.529989],[112.357812,25.541655],[112.369902,25.539422],[112.372418,25.530044],[112.367932,25.520442],[112.372144,25.512068],[112.392002,25.490961],[112.39802,25.476888],[112.399989,25.457172],[112.411805,25.440581],[112.420668,25.435498],[112.426904,25.423318],[112.439924,25.408287],[112.440963,25.399346],[112.426466,25.398508],[112.421324,25.39359],[112.435711,25.379952],[112.455186,25.38107],[112.458414,25.37509],[112.45256,25.365475],[112.444464,25.362736],[112.432867,25.368382],[112.420011,25.339087],[112.409508,25.32578],[112.394026,25.314595],[112.386094,25.313141],[112.374934,25.300837],[112.362188,25.298153],[112.345175,25.289259],[112.344901,25.284673],[112.357593,25.278631],[112.355405,25.263974],[112.360492,25.258547],[112.357593,25.244279],[112.368151,25.232696],[112.368096,25.222846],[112.36186,25.211988],[112.364212,25.191725]]]]}},{"type":"Feature","properties":{"adcode":431100,"name":"永州市","center":[111.608019,26.434516],"centroid":[111.734581,25.774386],"childrenNum":11,"level":"city","parent":{"adcode":430000},"subFeatureIndex":10,"acroutes":[100000,430000]},"geometry":{"type":"MultiPolygon","coordinates":[[[[112.364212,25.191725],[112.36186,25.211988],[112.368096,25.222846],[112.368151,25.232696],[112.357593,25.244279],[112.360492,25.258547],[112.355405,25.263974],[112.357593,25.278631],[112.344901,25.284673],[112.345175,25.289259],[112.362188,25.298153],[112.374934,25.300837],[112.386094,25.313141],[112.394026,25.314595],[112.409508,25.32578],[112.420011,25.339087],[112.432867,25.368382],[112.444464,25.362736],[112.45256,25.365475],[112.458414,25.37509],[112.455186,25.38107],[112.435711,25.379952],[112.421324,25.39359],[112.426466,25.398508],[112.440963,25.399346],[112.439924,25.408287],[112.426904,25.423318],[112.420668,25.435498],[112.411805,25.440581],[112.399989,25.457172],[112.39802,25.476888],[112.392002,25.490961],[112.372144,25.512068],[112.367932,25.520442],[112.372418,25.530044],[112.369902,25.539422],[112.357812,25.541655],[112.325591,25.529989],[112.312844,25.535013],[112.285766,25.555776],[112.270284,25.554883],[112.250973,25.559013],[112.246269,25.567608],[112.257702,25.573021],[112.260492,25.58234],[112.243643,25.589928],[112.238829,25.603876],[112.257429,25.634055],[112.257921,25.650452],[112.245612,25.672087],[112.243041,25.684855],[112.247363,25.703921],[112.278107,25.711167],[112.297363,25.730284],[112.310602,25.728891],[112.317002,25.723262],[112.321433,25.698458],[112.336422,25.690876],[112.343315,25.694277],[112.352068,25.712393],[112.361805,25.720196],[112.383523,25.730618],[112.392057,25.740315],[112.37756,25.750791],[112.377013,25.760486],[112.38686,25.789343],[112.385383,25.805552],[112.377068,25.803658],[112.361696,25.809116],[112.357101,25.818249],[112.359289,25.834398],[112.380514,25.837293],[112.387024,25.846258],[112.38686,25.859786],[112.377998,25.859285],[112.359562,25.894407],[112.360383,25.905871],[112.349715,25.906595],[112.33686,25.885725],[112.312407,25.890567],[112.288665,25.886282],[112.272089,25.886337],[112.265525,25.896689],[112.296816,25.931466],[112.315197,25.935806],[112.316783,25.944039],[112.309836,25.95611],[112.304475,25.953997],[112.299332,25.962507],[112.311532,25.962396],[112.292987,25.974298],[112.300426,25.978747],[112.306444,26.00694],[112.328545,26.039072],[112.33582,26.076641],[112.321816,26.093755],[112.309836,26.099033],[112.299715,26.090365],[112.291619,26.099977],[112.282593,26.101699],[112.271159,26.089032],[112.26186,26.092866],[112.251685,26.089588],[112.240579,26.09331],[112.230295,26.107032],[112.232428,26.117865],[112.231389,26.134417],[112.224332,26.138915],[112.222636,26.150799],[112.212571,26.151188],[112.217221,26.165459],[112.206115,26.165514],[112.195448,26.172011],[112.185929,26.185668],[112.192877,26.19394],[112.194901,26.206873],[112.190306,26.22369],[112.19605,26.229794],[112.200809,26.262365],[112.197308,26.277287],[112.205021,26.285275],[112.212461,26.30563],[112.20896,26.31356],[112.199004,26.30746],[112.190415,26.312229],[112.177942,26.305741],[112.177724,26.325925],[112.181498,26.34339],[112.158741,26.353036],[112.153161,26.349544],[112.148183,26.35736],[112.150152,26.38463],[112.141728,26.387068],[112.140634,26.407959],[112.153271,26.403139],[112.150098,26.416326],[112.152724,26.430065],[112.145612,26.431727],[112.143205,26.441477],[112.155295,26.444523],[112.161914,26.450727],[112.157975,26.465016],[112.152177,26.469668],[112.166509,26.477033],[112.159562,26.486336],[112.159999,26.493866],[112.1757,26.500178],[112.195339,26.486613],[112.211258,26.502725],[112.236695,26.505382],[112.243205,26.514073],[112.242713,26.535052],[112.227833,26.546453],[112.213118,26.548556],[112.19047,26.536879],[112.174223,26.524148],[112.15245,26.502725],[112.144737,26.504441],[112.147363,26.527469],[112.162735,26.539314],[112.149113,26.547173],[112.156389,26.555529],[112.169518,26.557078],[112.174715,26.571188],[112.168205,26.574674],[112.170557,26.585352],[112.158577,26.591825],[112.143916,26.593429],[112.141454,26.603386],[112.150317,26.617048],[112.151082,26.625731],[112.126356,26.63574],[112.115743,26.643371],[112.117822,26.650504],[112.10978,26.654043],[112.094189,26.645141],[112.093478,26.634026],[112.076903,26.64398],[112.05617,26.647961],[112.04583,26.643205],[112.028489,26.651831],[112.006498,26.648458],[111.995666,26.63939],[112.005513,26.624791],[112.013992,26.627556],[112.019736,26.619205],[112.014922,26.605322],[112.006005,26.596914],[111.997526,26.605101],[111.990196,26.624182],[111.973565,26.630929],[111.960983,26.645307],[111.959342,26.65642],[111.951902,26.664216],[111.949003,26.681519],[111.94036,26.699427],[111.927066,26.711032],[111.916399,26.733688],[111.917985,26.748936],[111.903325,26.751754],[111.874769,26.785888],[111.871486,26.796491],[111.859178,26.799584],[111.850206,26.789809],[111.831825,26.786164],[111.827504,26.780918],[111.817055,26.784011],[111.824057,26.798479],[111.820556,26.804498],[111.802504,26.801516],[111.797307,26.79257],[111.781278,26.789147],[111.771705,26.79986],[111.772142,26.80875],[111.753707,26.807038],[111.744735,26.812173],[111.745009,26.825534],[111.752285,26.831551],[111.746759,26.841487],[111.739046,26.832876],[111.731278,26.8326],[111.719243,26.847283],[111.712678,26.84916],[111.700589,26.843198],[111.701464,26.836188],[111.684615,26.833538],[111.66596,26.843309],[111.650862,26.840438],[111.642437,26.817252],[111.644516,26.803228],[111.638006,26.802344],[111.629637,26.789312],[111.618477,26.7913],[111.601245,26.785888],[111.588006,26.797596],[111.577229,26.79986],[111.575369,26.809357],[111.558083,26.808639],[111.549986,26.812338],[111.545938,26.821724],[111.549111,26.832324],[111.543586,26.840935],[111.53363,26.847117],[111.528269,26.865],[111.517218,26.86511],[111.507973,26.859536],[111.495227,26.860695],[111.482535,26.856776],[111.471485,26.861964],[111.462513,26.861081],[111.460106,26.867097],[111.4455,26.867593],[111.43817,26.86086],[111.430019,26.867924],[111.419625,26.867814],[111.406441,26.858211],[111.392437,26.863013],[111.372907,26.858211],[111.366397,26.864944],[111.349657,26.859812],[111.349712,26.851533],[111.329854,26.836685],[111.321922,26.820123],[111.322524,26.813111],[111.315139,26.802565],[111.32411,26.788318],[111.321485,26.783127],[111.329198,26.772136],[111.329417,26.757609],[111.324001,26.737721],[111.317218,26.733191],[111.32143,26.714238],[111.309067,26.710922],[111.30294,26.700035],[111.276244,26.68887],[111.281112,26.678699],[111.293694,26.67284],[111.299384,26.660677],[111.301244,26.644201],[111.312568,26.639003],[111.314263,26.626616],[111.306058,26.619758],[111.30387,26.60405],[111.304581,26.58336],[111.297688,26.576943],[111.297031,26.567758],[111.288498,26.557078],[111.296047,26.526196],[111.296922,26.511748],[111.288771,26.492316],[111.278268,26.490212],[111.271867,26.499403],[111.263388,26.493423],[111.259723,26.479913],[111.251353,26.483844],[111.229635,26.481131],[111.203322,26.462856],[111.201189,26.457318],[111.181057,26.463355],[111.184668,26.470499],[111.168038,26.474154],[111.15551,26.48246],[111.158847,26.49442],[111.154416,26.500399],[111.165959,26.511748],[111.15923,26.515734],[111.153978,26.527026],[111.142272,26.541306],[111.12586,26.553924],[111.127118,26.577496],[111.133191,26.590773],[111.137129,26.610632],[111.127447,26.623076],[111.10923,26.617435],[111.11388,26.609249],[111.104744,26.585905],[111.088716,26.588893],[111.073562,26.587841],[111.067107,26.577274],[111.063934,26.558406],[111.06656,26.541306],[111.063278,26.526528],[111.067217,26.505548],[111.05644,26.486613],[111.060269,26.473766],[111.052665,26.457041],[111.043694,26.451225],[111.044952,26.440923],[111.031768,26.432503],[111.019186,26.401033],[111.019022,26.391058],[111.025094,26.384575],[111.01656,26.366007],[111.008573,26.358857],[111.00261,26.340119],[111.0083,26.337014],[111.026188,26.337403],[111.043201,26.332468],[111.040357,26.323486],[111.053486,26.319493],[111.061199,26.325371],[111.06481,26.318883],[111.079361,26.318218],[111.0926,26.306683],[111.106878,26.304077],[111.116396,26.309179],[111.135817,26.306517],[111.157808,26.30746],[111.168913,26.31051],[111.177775,26.307127],[111.204745,26.307848],[111.20923,26.30269],[111.208847,26.290932],[111.203322,26.280671],[111.212841,26.269133],[111.225423,26.269466],[111.231659,26.262309],[111.240521,26.26708],[111.247852,26.263641],[111.252447,26.269244],[111.267874,26.273071],[111.281277,26.27113],[111.2926,26.252434],[111.295336,26.240338],[111.291452,26.220804],[111.271703,26.217196],[111.270664,26.200767],[111.266506,26.191331],[111.274384,26.182559],[111.268913,26.16879],[111.258136,26.152021],[111.262403,26.135861],[111.26864,26.129307],[111.268913,26.107366],[111.25934,26.096699],[111.265959,26.096032],[111.244624,26.077975],[111.252666,26.068139],[111.26492,26.061248],[111.264318,26.055691],[111.252939,26.056691],[111.236802,26.048855],[111.23051,26.034458],[111.213716,26.01767],[111.215357,26.011777],[111.202939,25.976133],[111.196703,25.97085],[111.196101,25.960894],[111.189537,25.953274],[111.205018,25.952884],[111.20655,25.939645],[111.219679,25.93703],[111.216615,25.928963],[111.232261,25.911046],[111.222469,25.907318],[111.229143,25.897524],[111.24271,25.887784],[111.251627,25.864685],[111.259887,25.861066],[111.278541,25.860287],[111.291889,25.854442],[111.297086,25.874259],[111.305292,25.883666],[111.326517,25.89552],[111.327611,25.900195],[111.346211,25.906316],[111.355019,25.892126],[111.362568,25.892292],[111.365248,25.900585],[111.378432,25.904758],[111.378815,25.894073],[111.385489,25.882107],[111.408684,25.885057],[111.41585,25.876875],[111.432207,25.88695],[111.440632,25.884946],[111.454253,25.888452],[111.456824,25.871086],[111.470993,25.875261],[111.492054,25.868581],[111.486201,25.859341],[111.465139,25.855833],[111.456879,25.848095],[111.433246,25.846258],[111.425041,25.826268],[111.436091,25.813571],[111.442273,25.778091],[111.440194,25.769623],[111.432863,25.766615],[111.416069,25.768174],[111.399603,25.744606],[111.346813,25.729671],[111.327283,25.732736],[111.318695,25.729504],[111.307535,25.716351],[111.308738,25.692326],[111.313935,25.682625],[111.309778,25.658091],[111.309997,25.64493],[111.317655,25.631266],[111.334723,25.618381],[111.343148,25.602761],[111.336857,25.595787],[111.324931,25.564148],[111.323892,25.548856],[111.327721,25.537413],[111.328104,25.521447],[111.320609,25.49554],[111.300861,25.46974],[111.301244,25.451084],[111.292108,25.435833],[111.280839,25.430078],[111.278979,25.423318],[111.26585,25.425441],[111.256933,25.407616],[111.25748,25.395937],[111.242163,25.387833],[111.236692,25.378164],[111.227994,25.375425],[111.210543,25.363519],[111.181823,25.366593],[111.16388,25.342386],[111.155456,25.324382],[111.138442,25.303578],[111.119514,25.290825],[111.103322,25.285064],[111.109504,25.266268],[111.109832,25.252728],[111.117819,25.239299],[111.112786,25.217081],[111.077884,25.201073],[111.065466,25.18747],[111.054963,25.187694],[111.047249,25.179017],[111.034613,25.179129],[111.00272,25.165747],[111.000532,25.150013],[110.994459,25.146261],[110.982807,25.126659],[110.97761,25.108958],[110.983956,25.101676],[110.961418,25.077864],[110.966724,25.073101],[110.956166,25.058812],[110.951899,25.041157],[110.957479,25.024902],[110.9554,25.016886],[110.960761,25.001524],[110.975477,24.987787],[110.968748,24.975506],[110.973453,24.968272],[110.985542,24.966028],[110.992107,24.959018],[110.987238,24.942527],[110.994897,24.930354],[110.983737,24.924183],[110.979142,24.914701],[110.997195,24.927044],[111.003431,24.921434],[111.014536,24.92379],[111.018529,24.929793],[111.030346,24.931981],[111.050258,24.928278],[111.08609,24.941125],[111.097414,24.9409],[111.100423,24.945724],[111.096976,24.974889],[111.102064,24.982292],[111.107917,25.00971],[111.101845,25.035216],[111.123016,25.042559],[111.140029,25.04239],[111.167162,25.060605],[111.200751,25.07467],[111.206714,25.08498],[111.219296,25.093552],[111.222031,25.106437],[111.249493,25.128675],[111.263716,25.133604],[111.263224,25.143796],[111.274767,25.151133],[111.289099,25.142452],[111.296703,25.122066],[111.310981,25.116184],[111.321813,25.104925],[111.347141,25.101115],[111.36038,25.103076],[111.367874,25.108846],[111.37515,25.128507],[111.387076,25.130243],[111.399767,25.124586],[111.402831,25.107558],[111.412677,25.100723],[111.429089,25.103468],[111.436693,25.098426],[111.418804,25.065592],[111.416561,25.047659],[111.4234,25.035496],[111.439319,25.027481],[111.465303,25.023781],[111.468312,25.019464],[111.467327,25.002477],[111.460489,24.992777],[111.438389,24.98431],[111.431113,24.97259],[111.431386,24.959691],[111.440194,24.944547],[111.462185,24.930803],[111.470227,24.928952],[111.463936,24.908978],[111.453159,24.904602],[111.447087,24.893098],[111.45945,24.882323],[111.460489,24.872221],[111.449439,24.857066],[111.452995,24.844211],[111.471102,24.82063],[111.479417,24.797551],[111.470446,24.773456],[111.467163,24.758064],[111.461255,24.750086],[111.464155,24.733849],[111.437295,24.697433],[111.431113,24.685854],[111.435489,24.68102],[111.446758,24.682538],[111.451791,24.665786],[111.468039,24.666741],[111.471594,24.674668],[111.48538,24.672982],[111.504144,24.664886],[111.514319,24.655103],[111.52154,24.642171],[111.52991,24.636548],[111.549877,24.648581],[111.560107,24.63891],[111.570719,24.644702],[111.580348,24.674724],[111.589155,24.690688],[111.597689,24.693892],[111.619297,24.683718],[111.636639,24.681357],[111.641672,24.684674],[111.643367,24.701311],[111.637788,24.71553],[111.642328,24.730028],[111.666453,24.760817],[111.689593,24.778567],[111.70398,24.778174],[111.708411,24.788846],[111.733247,24.780252],[111.761858,24.782106],[111.783466,24.785757],[111.794243,24.774298],[111.814101,24.77031],[111.835272,24.776938],[111.856388,24.772051],[111.868696,24.771827],[111.868915,24.760311],[111.875206,24.75666],[111.903707,24.763457],[111.924605,24.757053],[111.938226,24.756997],[111.950972,24.769636],[111.963554,24.770085],[111.970119,24.763738],[111.99769,24.758907],[112.024113,24.740142],[112.033577,24.753457],[112.033795,24.771153],[112.0542,24.788902],[112.059233,24.799516],[112.083796,24.804851],[112.096487,24.817261],[112.097253,24.826358],[112.112625,24.831523],[112.124058,24.841123],[112.141454,24.844492],[112.149496,24.836969],[112.161093,24.844211],[112.17105,24.862735],[112.165689,24.867226],[112.165306,24.882492],[112.174058,24.913972],[112.175207,24.927493],[112.15245,24.93243],[112.142111,24.937927],[112.12001,24.963729],[112.122034,24.989525],[112.134671,24.995861],[112.155732,25.026976],[112.148894,25.03544],[112.153544,25.045473],[112.152177,25.055953],[112.164266,25.0717],[112.165579,25.083691],[112.177122,25.10739],[112.174168,25.129515],[112.183249,25.1401],[112.183304,25.148837],[112.19315,25.172186],[112.187133,25.182544],[112.201739,25.185791],[112.246542,25.184951],[112.255569,25.17157],[112.256061,25.159364],[112.281991,25.164739],[112.286969,25.158972],[112.30256,25.15718],[112.315963,25.17521],[112.332429,25.174538],[112.350864,25.187022],[112.364212,25.191725]]]]}},{"type":"Feature","properties":{"adcode":431200,"name":"怀化市","center":[109.97824,27.550082],"centroid":[110.082325,27.552517],"childrenNum":12,"level":"city","parent":{"adcode":430000},"subFeatureIndex":11,"acroutes":[100000,430000]},"geometry":{"type":"MultiPolygon","coordinates":[[[[109.418415,27.721364],[109.418251,27.714244],[109.429957,27.703564],[109.456872,27.69354],[109.470439,27.680283],[109.458185,27.67475],[109.456161,27.669436],[109.464476,27.651408],[109.470056,27.628774],[109.469181,27.620936],[109.451238,27.585959],[109.46196,27.565615],[109.45917,27.560131],[109.445986,27.562379],[109.433623,27.548393],[109.404957,27.550478],[109.379137,27.535832],[109.325909,27.494243],[109.312342,27.486176],[109.302988,27.475638],[109.306926,27.434411],[109.299869,27.423923],[109.286467,27.424637],[109.245548,27.418157],[109.24325,27.429634],[109.221915,27.438913],[109.213709,27.450497],[109.202112,27.450058],[109.18953,27.436552],[109.166992,27.417828],[109.156215,27.41651],[109.159442,27.442317],[109.154081,27.448795],[109.140405,27.447094],[109.123337,27.42859],[109.123282,27.418432],[109.11453,27.424911],[109.111959,27.413709],[109.124541,27.415137],[109.129245,27.42557],[109.138655,27.430348],[109.14221,27.418212],[109.127659,27.405087],[109.115897,27.400089],[109.12476,27.387895],[109.113819,27.367184],[109.118468,27.36224],[109.114092,27.352404],[109.104519,27.355481],[109.101072,27.349822],[109.103753,27.337128],[109.086357,27.331028],[109.074376,27.331907],[109.072188,27.323553],[109.059551,27.326851],[109.052112,27.336688],[109.044398,27.331083],[109.054136,27.306074],[109.053917,27.294859],[109.045602,27.288207],[109.041389,27.276606],[109.023884,27.282214],[109.010591,27.270502],[108.99954,27.267533],[108.987177,27.270557],[108.984661,27.256259],[108.968523,27.245535],[108.963435,27.235524],[108.951455,27.236074],[108.947078,27.228428],[108.914256,27.21462],[108.908676,27.204332],[108.925744,27.1996],[108.919179,27.193492],[108.929792,27.180065],[108.926017,27.175167],[108.926783,27.160912],[108.909989,27.147536],[108.904901,27.134929],[108.887614,27.121495],[108.88477,27.108499],[108.878752,27.106296],[108.868522,27.116594],[108.859934,27.114887],[108.856542,27.098091],[108.846969,27.098146],[108.824376,27.089058],[108.807472,27.098587],[108.792209,27.083275],[108.803807,27.078869],[108.831432,27.057825],[108.840951,27.063059],[108.845656,27.058045],[108.84396,27.047963],[108.854737,27.031983],[108.868522,27.031047],[108.877658,27.015451],[108.878424,27.006356],[108.872899,26.999852],[108.884113,27.002388],[108.900634,27.016939],[108.918468,27.019088],[108.914912,27.025922],[108.920984,27.029779],[108.921367,27.009774],[108.936794,27.011813],[108.951947,27.018757],[108.950962,27.036943],[108.94314,27.037384],[108.940404,27.044712],[108.964256,27.054464],[108.989639,27.074076],[109.007582,27.080246],[109.016116,27.086745],[109.018851,27.095833],[109.032527,27.103818],[109.035864,27.098091],[109.053753,27.098311],[109.061958,27.110427],[109.064748,27.103488],[109.080394,27.116484],[109.097188,27.116098],[109.111357,27.123146],[109.122954,27.123367],[109.13395,27.11775],[109.131051,27.110096],[109.118961,27.10525],[109.109169,27.092528],[109.101127,27.068953],[109.130558,27.065042],[109.141062,27.073581],[109.1543,27.071928],[109.163545,27.065813],[109.175252,27.087241],[109.185482,27.082284],[109.19593,27.091262],[109.21825,27.116429],[109.238928,27.149132],[109.248119,27.153426],[109.257419,27.150618],[109.264257,27.131901],[109.280559,27.127111],[109.29894,27.135259],[109.335045,27.139058],[109.333677,27.148747],[109.358732,27.152875],[109.373994,27.147811],[109.376894,27.154196],[109.384552,27.143902],[109.393196,27.143847],[109.392813,27.156068],[109.400855,27.159591],[109.400253,27.15238],[109.41464,27.154141],[109.427933,27.12601],[109.440898,27.118191],[109.448338,27.120558],[109.457583,27.133332],[109.472682,27.134929],[109.469345,27.115438],[109.459607,27.108279],[109.463437,27.10123],[109.459717,27.09363],[109.462069,27.081292],[109.482419,27.081127],[109.481653,27.071763],[109.454575,27.069449],[109.468251,27.064767],[109.487069,27.053968],[109.49615,27.062453],[109.487999,27.066474],[109.489804,27.078593],[109.498503,27.079364],[109.505067,27.072699],[109.518524,27.072589],[109.510483,27.067962],[109.518853,27.060029],[109.517923,27.043224],[109.525034,27.037273],[109.5258,27.026528],[109.541336,27.01286],[109.542376,26.996435],[109.532091,26.993182],[109.527605,26.977195],[109.536796,26.974659],[109.546697,26.984583],[109.555013,26.946923],[109.533623,26.938596],[109.530231,26.92751],[109.514093,26.930764],[109.493251,26.921111],[109.484225,26.913554],[109.471807,26.911182],[109.45824,26.901859],[109.446588,26.899652],[109.436413,26.892645],[109.438546,26.877416],[109.444837,26.871732],[109.436631,26.862461],[109.447901,26.859591],[109.457474,26.864117],[109.456763,26.873222],[109.472955,26.884755],[109.474214,26.8943],[109.486796,26.895293],[109.490844,26.883651],[109.51382,26.874271],[109.510373,26.865496],[109.513109,26.840273],[109.497354,26.823105],[109.497463,26.815265],[109.507693,26.801185],[109.51754,26.779924],[109.517485,26.756228],[109.522244,26.749378],[109.528645,26.744019],[109.53417,26.744572],[109.553918,26.73529],[109.561522,26.742251],[109.558076,26.754626],[109.570439,26.747887],[109.580341,26.755676],[109.577113,26.77059],[109.596424,26.760703],[109.579083,26.740815],[109.578153,26.733301],[109.568251,26.726173],[109.553371,26.723024],[109.547299,26.717885],[109.546041,26.731201],[109.528535,26.743909],[109.522135,26.749212],[109.504629,26.744627],[109.502332,26.757664],[109.497682,26.76015],[109.453973,26.7612],[109.437671,26.755234],[109.417758,26.739765],[109.413984,26.72225],[109.407091,26.719819],[109.38127,26.727444],[109.385975,26.712138],[109.37301,26.705009],[109.364968,26.696166],[109.355012,26.693237],[109.335592,26.699979],[109.319126,26.701748],[109.298447,26.696553],[109.292922,26.701251],[109.283732,26.698598],[109.287014,26.689699],[109.304191,26.66311],[109.33406,26.646247],[109.355121,26.659019],[109.364366,26.633473],[109.378699,26.622468],[109.384717,26.604713],[109.391281,26.60051],[109.387178,26.588063],[109.389859,26.581147],[109.385482,26.571022],[109.399049,26.570967],[109.395165,26.56643],[109.403973,26.560177],[109.408732,26.5371],[109.404301,26.529628],[109.381708,26.518502],[109.385537,26.493534],[109.364038,26.475926],[109.362452,26.466235],[109.380997,26.461749],[109.373557,26.449453],[109.361029,26.44829],[109.326784,26.42796],[109.319563,26.418653],[109.313546,26.397376],[109.299049,26.368225],[109.292594,26.345331],[109.277331,26.340008],[109.271423,26.327755],[109.274486,26.31539],[109.285865,26.295813],[109.296861,26.297366],[109.30534,26.29121],[109.325745,26.289879],[109.323393,26.282446],[109.334771,26.276677],[109.339804,26.264084],[109.351456,26.264251],[109.373229,26.278175],[109.391172,26.277121],[109.401511,26.283722],[109.421041,26.288714],[109.442649,26.289879],[109.444454,26.303079],[109.46103,26.314114],[109.466555,26.314059],[109.476894,26.299252],[109.458842,26.284166],[109.453426,26.264528],[109.43964,26.238839],[109.452386,26.209648],[109.468306,26.20321],[109.470439,26.196327],[109.459334,26.194106],[109.470001,26.177007],[109.467485,26.162349],[109.476183,26.148078],[109.493196,26.144024],[109.495166,26.152632],[109.501128,26.139082],[109.514093,26.128251],[109.512726,26.115476],[109.504082,26.09681],[109.475964,26.099477],[109.466555,26.091588],[109.450417,26.101921],[109.450964,26.075974],[109.447572,26.071807],[109.454793,26.053079],[109.479137,26.047743],[109.482638,26.029622],[109.496424,26.023785],[109.508896,26.009553],[109.513163,25.998099],[109.5287,25.995764],[109.540297,26.000045],[109.545385,26.013889],[109.559772,26.02145],[109.588273,26.019727],[109.604466,26.026398],[109.612726,26.037071],[109.634991,26.047298],[109.646041,26.041962],[109.649269,26.01678],[109.656709,26.013445],[109.675472,26.015113],[109.690133,26.007551],[109.689149,25.998266],[109.698066,25.998933],[109.708241,26.013556],[109.72323,26.003437],[109.729685,25.991538],[109.723558,25.974632],[109.711468,25.961784],[109.709991,25.954052],[109.69347,25.95917],[109.690297,25.937642],[109.682584,25.933914],[109.679302,25.923065],[109.69254,25.909933],[109.69254,25.898025],[109.68521,25.901085],[109.68056,25.895131],[109.688711,25.888285],[109.68521,25.880326],[109.702114,25.882274],[109.710648,25.886894],[109.7194,25.883833],[109.747245,25.889231],[109.768361,25.890345],[109.764751,25.876207],[109.779521,25.865965],[109.799379,25.871866],[109.813219,25.879825],[109.815845,25.890845],[109.825965,25.911436],[109.825035,25.922898],[109.810429,25.945653],[109.80649,25.973631],[109.784663,25.985754],[109.782475,25.997209],[109.80195,26.034403],[109.814587,26.040962],[109.840189,26.029066],[109.856272,26.026287],[109.870878,26.033347],[109.880451,26.057302],[109.882475,26.075252],[109.888165,26.087976],[109.898996,26.095199],[109.899051,26.108977],[109.907202,26.144857],[109.914478,26.154409],[109.931217,26.161239],[109.966228,26.195494],[109.974379,26.218362],[109.99276,26.238617],[109.988821,26.245165],[109.995331,26.258703],[109.990408,26.27285],[109.984281,26.279118],[109.995933,26.294981],[110.009281,26.304021],[110.013001,26.335074],[110.017706,26.347548],[110.011524,26.364622],[110.012235,26.372492],[109.978646,26.388011],[109.979412,26.40735],[109.98729,26.432447],[109.96683,26.428016],[109.950583,26.43699],[109.955014,26.446905],[109.934883,26.456986],[109.932585,26.475981],[109.919018,26.474652],[109.902826,26.461804],[109.891392,26.459367],[109.875418,26.468173],[109.856272,26.465182],[109.862344,26.486834],[109.879357,26.497022],[109.883187,26.509977],[109.879685,26.517395],[109.892541,26.525477],[109.8723,26.538871],[109.862672,26.539867],[109.864368,26.561007],[109.872081,26.571022],[109.861688,26.583637],[109.856819,26.580926],[109.826841,26.60582],[109.83067,26.621528],[109.851458,26.621804],[109.858241,26.643427],[109.885429,26.653822],[109.898942,26.655591],[109.901075,26.66803],[109.91404,26.676212],[109.934062,26.673724],[109.941939,26.67776],[109.950036,26.68887],[109.963603,26.691855],[109.987618,26.685333],[109.997738,26.674277],[110.007476,26.673116],[110.002005,26.666593],[110.020331,26.662889],[110.021863,26.668251],[110.036907,26.681961],[110.044183,26.6981],[110.065189,26.695392],[110.072082,26.700145],[110.067323,26.718382],[110.060813,26.717553],[110.047465,26.724681],[110.05031,26.735622],[110.056546,26.740207],[110.04927,26.747555],[110.064095,26.750925],[110.061688,26.760316],[110.068253,26.759653],[110.063493,26.769927],[110.068581,26.784618],[110.061634,26.793509],[110.056546,26.80886],[110.057421,26.822718],[110.048723,26.825037],[110.042104,26.835029],[110.048668,26.86075],[110.055944,26.876202],[110.063548,26.882051],[110.078209,26.881996],[110.093253,26.891155],[110.09741,26.906383],[110.072137,26.932032],[110.075911,26.941684],[110.089697,26.948743],[110.104796,26.951941],[110.116284,26.978022],[110.125529,26.984803],[110.146262,26.986898],[110.153647,26.998419],[110.15031,27.022891],[110.155069,27.037714],[110.162619,27.04642],[110.201404,27.061902],[110.208352,27.081292],[110.204413,27.092033],[110.194183,27.102111],[110.200474,27.118191],[110.226514,27.130359],[110.24949,27.151059],[110.26705,27.153866],[110.304632,27.166966],[110.31437,27.157939],[110.325803,27.158765],[110.331766,27.151444],[110.342707,27.150508],[110.355891,27.175277],[110.352116,27.19905],[110.375584,27.223037],[110.387127,27.218801],[110.424053,27.19949],[110.443035,27.201251],[110.456274,27.2133],[110.462127,27.247075],[110.483517,27.262144],[110.511635,27.273746],[110.526405,27.289911],[110.524272,27.293375],[110.540847,27.305194],[110.553922,27.308218],[110.573998,27.281059],[110.585104,27.278585],[110.598725,27.281444],[110.609064,27.288977],[110.606384,27.301841],[110.609994,27.309537],[110.606548,27.32108],[110.614863,27.324103],[110.632204,27.343283],[110.636526,27.353613],[110.649218,27.365206],[110.659666,27.396793],[110.663113,27.420683],[110.674108,27.434575],[110.688222,27.443854],[110.69331,27.455822],[110.684666,27.468722],[110.68401,27.487877],[110.68029,27.497042],[110.648233,27.529578],[110.632642,27.536106],[110.638112,27.555908],[110.652773,27.565834],[110.653047,27.57417],[110.674053,27.60005],[110.710542,27.606958],[110.714426,27.616003],[110.734174,27.616386],[110.741067,27.62565],[110.743693,27.617318],[110.737949,27.600708],[110.746647,27.603833],[110.755837,27.596815],[110.767052,27.581299],[110.776898,27.574005],[110.7868,27.560515],[110.799437,27.559418],[110.808682,27.563366],[110.824328,27.578831],[110.853485,27.592045],[110.854579,27.601804],[110.847632,27.608986],[110.845662,27.62428],[110.857314,27.621375],[110.852336,27.627568],[110.855564,27.647353],[110.869185,27.655463],[110.86831,27.672887],[110.859995,27.677215],[110.849163,27.675791],[110.837511,27.681489],[110.830345,27.714956],[110.811472,27.757775],[110.795717,27.758158],[110.785706,27.782681],[110.767763,27.795433],[110.78587,27.832914],[110.791614,27.85567],[110.806548,27.864257],[110.837183,27.849216],[110.87668,27.846371],[110.882096,27.850474],[110.894514,27.849872],[110.898507,27.855998],[110.912785,27.864257],[110.922358,27.863273],[110.929689,27.879077],[110.944787,27.896247],[110.973945,27.910899],[110.9804,27.919973],[110.970772,27.925276],[110.966669,27.949269],[110.987402,27.972875],[111.000532,27.992214],[110.990958,27.992979],[110.971155,28.002757],[110.9804,28.029081],[111.013223,28.028917],[111.022031,28.041531],[111.010488,28.044534],[110.992162,28.054034],[110.971319,28.054798],[110.970936,28.065826],[110.962676,28.058129],[110.953485,28.057091],[110.955728,28.050758],[110.942982,28.038364],[110.938059,28.018486],[110.92575,28.021326],[110.92203,28.000626],[110.907698,27.998223],[110.88959,28.000954],[110.878157,28.01308],[110.866177,28.013735],[110.86645,28.025477],[110.884065,28.050977],[110.896155,28.058784],[110.876352,28.081819],[110.858846,28.076361],[110.83319,28.087496],[110.823452,28.087441],[110.844349,28.116364],[110.833026,28.118874],[110.818638,28.13966],[110.849163,28.172277],[110.853266,28.188418],[110.860487,28.198614],[110.858518,28.205157],[110.84889,28.204721],[110.848069,28.213007],[110.840082,28.214643],[110.826789,28.209082],[110.824601,28.203794],[110.804579,28.213225],[110.79982,28.223201],[110.787839,28.231268],[110.806275,28.253013],[110.802719,28.264348],[110.793036,28.275898],[110.783354,28.278241],[110.774601,28.27312],[110.74971,28.280911],[110.739535,28.281619],[110.7211,28.300794],[110.733189,28.311361],[110.741067,28.325466],[110.753266,28.338698],[110.793966,28.354379],[110.825914,28.37169],[110.832752,28.380508],[110.83587,28.393896],[110.853923,28.398468],[110.860433,28.406032],[110.862129,28.418818],[110.88866,28.438948],[110.889207,28.447325],[110.905345,28.455103],[110.923453,28.473268],[110.929744,28.484796],[110.943803,28.478434],[110.959339,28.492245],[110.969897,28.512524],[110.981658,28.51198],[110.993146,28.521765],[111.002009,28.537146],[111.013168,28.545787],[111.029689,28.543668],[111.041888,28.535027],[111.049274,28.53682],[111.067545,28.530135],[111.075915,28.53019],[111.079306,28.53769],[111.054744,28.57062],[111.064481,28.582789],[111.055346,28.590177],[111.057425,28.607938],[111.049766,28.608156],[111.036691,28.596858],[111.020171,28.589742],[111.015794,28.599302],[111.008026,28.598162],[111.010105,28.587352],[111.005729,28.583604],[110.989262,28.587841],[110.978376,28.585505],[110.956166,28.568827],[110.950696,28.568229],[110.943857,28.591644],[110.945936,28.601421],[110.934722,28.617551],[110.946155,28.622004],[110.9554,28.61918],[110.991724,28.619995],[110.995335,28.63786],[111.015247,28.649858],[111.051681,28.652301],[111.064646,28.659739],[111.06191,28.668587],[111.046648,28.684707],[111.051571,28.692088],[111.06574,28.696592],[111.081166,28.69187],[111.09632,28.700499],[111.105455,28.727085],[111.102556,28.734028],[111.115138,28.743358],[111.098453,28.770747],[111.102228,28.777959],[111.086309,28.785387],[111.078759,28.793682],[111.079361,28.805717],[111.072742,28.809837],[111.064427,28.823442],[111.048453,28.825393],[111.040302,28.822683],[111.031494,28.838075],[111.013114,28.851297],[111.002063,28.875732],[110.992435,28.888245],[110.9897,28.89729],[110.972687,28.904223],[110.9583,28.906389],[110.96284,28.917924],[110.950148,28.937308],[110.956768,28.951059],[110.954908,28.960748],[110.965356,28.965186],[110.974602,28.976769],[110.982588,28.976823],[110.98702,28.988404],[110.970717,28.992733],[110.962019,28.99836],[110.949,28.997007],[110.955291,29.002851],[110.943529,29.011778],[110.919076,29.022544],[110.9147,29.035742],[110.903814,29.034769],[110.903102,29.0213],[110.915137,29.008532],[110.905126,28.995709],[110.898452,29.00112],[110.889153,28.992462],[110.860706,28.998955],[110.840465,28.99257],[110.839371,28.987754],[110.850258,28.968542],[110.851844,28.952033],[110.849163,28.946511],[110.8368,28.941855],[110.811417,28.955281],[110.798616,28.955227],[110.798069,28.935738],[110.788879,28.913808],[110.775695,28.906172],[110.76366,28.905847],[110.739371,28.924476],[110.730454,28.926154],[110.716942,28.913429],[110.690903,28.923988],[110.690684,28.908122],[110.678594,28.906172],[110.670498,28.91083],[110.666504,28.923501],[110.656986,28.935034],[110.635979,28.949705],[110.620716,28.965186],[110.593309,28.969354],[110.572576,29.000579],[110.558408,28.995438],[110.541777,28.982289],[110.553539,28.963346],[110.551077,28.953278],[110.533243,28.946132],[110.521919,28.938499],[110.521044,28.93276],[110.538987,28.908447],[110.543966,28.889328],[110.530782,28.874107],[110.524381,28.886132],[110.490191,28.911263],[110.4839,28.910776],[110.476569,28.898807],[110.481766,28.889437],[110.472138,28.887487],[110.468035,28.880228],[110.450913,28.882828],[110.449162,28.889816],[110.432805,28.890791],[110.423123,28.900594],[110.400201,28.89572],[110.390409,28.881149],[110.396317,28.864192],[110.377608,28.850268],[110.365901,28.846095],[110.344785,28.820732],[110.340464,28.80176],[110.342597,28.782025],[110.340409,28.769825],[110.33089,28.760063],[110.310868,28.757135],[110.288275,28.767439],[110.283844,28.762721],[110.28554,28.743521],[110.271536,28.700716],[110.273724,28.689428],[110.270278,28.671409],[110.257695,28.672386],[110.251076,28.659956],[110.244019,28.658164],[110.243363,28.644755],[110.228647,28.653116],[110.218582,28.644158],[110.212072,28.625697],[110.230835,28.615922],[110.224544,28.612066],[110.229905,28.587569],[110.236634,28.57339],[110.224216,28.563285],[110.211087,28.566545],[110.207531,28.575129],[110.188603,28.574966],[110.185868,28.582735],[110.172465,28.584256],[110.167542,28.574749],[110.165463,28.556982],[110.167104,28.535027],[110.150857,28.527798],[110.148614,28.483654],[110.163603,28.467558],[110.15775,28.461412],[110.141667,28.456517],[110.138111,28.447706],[110.126349,28.44863],[110.127389,28.459944],[110.109227,28.463642],[110.10299,28.45271],[110.114205,28.442538],[110.110375,28.425239],[110.111743,28.415935],[110.125802,28.402495],[110.141448,28.383338],[110.152061,28.391719],[110.170058,28.378058],[110.179796,28.37648],[110.190409,28.363252],[110.205835,28.362599],[110.211525,28.346974],[110.203045,28.339787],[110.185047,28.333144],[110.1781,28.316426],[110.178428,28.3027],[110.185759,28.285705],[110.175037,28.280529],[110.186525,28.259389],[110.205999,28.252523],[110.208844,28.243803],[110.226514,28.24086],[110.240299,28.230832],[110.24298,28.207229],[110.235923,28.197688],[110.223013,28.198069],[110.216667,28.204394],[110.191448,28.201231],[110.202006,28.187873],[110.194293,28.173477],[110.174544,28.165733],[110.169183,28.155588],[110.182258,28.145715],[110.177881,28.133987],[110.154905,28.13044],[110.151787,28.120893],[110.166338,28.110635],[110.166776,28.103104],[110.147301,28.092189],[110.123176,28.093663],[110.111743,28.090934],[110.116284,28.075542],[110.124489,28.065771],[110.137454,28.057801],[110.137509,28.047264],[110.130835,28.03962],[110.122192,28.040002],[110.128592,28.024821],[110.117706,28.016411],[110.111141,28.005542],[110.110321,27.988554],[110.09927,27.977082],[110.06962,27.96834],[110.062454,27.959269],[110.047848,27.950034],[110.053975,27.933146],[110.044292,27.918661],[110.02252,27.908001],[110.016064,27.908603],[110.000364,27.919755],[110.001732,27.936153],[109.984117,27.945935],[109.974106,27.93812],[109.970277,27.956865],[109.958406,27.961182],[109.957913,27.951673],[109.951513,27.94834],[109.947793,27.956865],[109.933624,27.959269],[109.914368,27.951236],[109.909335,27.93741],[109.882585,27.946919],[109.876841,27.956318],[109.857147,27.970908],[109.837453,27.975005],[109.842158,27.984402],[109.833186,27.986205],[109.816118,27.980906],[109.797847,27.979322],[109.792924,27.973913],[109.77591,27.999097],[109.784444,28.006744],[109.784718,28.021436],[109.790134,28.029736],[109.752442,28.02149],[109.732201,28.02362],[109.736031,28.012424],[109.730834,28.00516],[109.733077,27.987407],[109.719783,27.98178],[109.713383,27.96752],[109.719127,27.952657],[109.711249,27.949815],[109.696096,27.936972],[109.681982,27.935934],[109.670713,27.921668],[109.661523,27.919536],[109.649871,27.903956],[109.63045,27.90997],[109.622737,27.89324],[109.622518,27.878859],[109.63696,27.876015],[109.643142,27.861905],[109.640516,27.856053],[109.647628,27.843308],[109.647409,27.834993],[109.636796,27.827334],[109.623175,27.826623],[109.626676,27.817103],[109.613383,27.815625],[109.603372,27.79817],[109.59626,27.804627],[109.585975,27.802766],[109.573776,27.808895],[109.559662,27.799209],[109.549761,27.786184],[109.540953,27.786513],[109.533021,27.795871],[109.532802,27.811522],[109.52126,27.812507],[109.51196,27.80014],[109.507255,27.802821],[109.492649,27.795762],[109.485866,27.787881],[109.47673,27.788702],[109.479192,27.799428],[109.475144,27.804736],[109.461358,27.803423],[109.454465,27.794886],[109.461522,27.773322],[109.451128,27.765056],[109.442704,27.74918],[109.426402,27.738941],[109.418415,27.721364]]],[[[109.466938,26.831937],[109.468634,26.826527],[109.482146,26.835029],[109.466938,26.831937]]],[[[109.528535,26.743909],[109.528645,26.744019],[109.522244,26.749378],[109.522135,26.749212],[109.528535,26.743909]]]]}},{"type":"Feature","properties":{"adcode":431300,"name":"娄底市","center":[112.008497,27.728136],"centroid":[111.617993,27.73631],"childrenNum":5,"level":"city","parent":{"adcode":430000},"subFeatureIndex":12,"acroutes":[100000,430000]},"geometry":{"type":"MultiPolygon","coordinates":[[[[112.092165,27.205652],[112.107209,27.214125],[112.114211,27.210714],[112.112625,27.222322],[112.129529,27.220892],[112.127942,27.227658],[112.137899,27.237009],[112.154091,27.239375],[112.160054,27.247515],[112.1507,27.254609],[112.150535,27.265828],[112.163063,27.277321],[112.162844,27.284193],[112.153654,27.305689],[112.163883,27.324542],[112.174824,27.319651],[112.182374,27.309812],[112.190634,27.311791],[112.197691,27.295794],[112.20535,27.296564],[112.206225,27.285128],[112.213938,27.268908],[112.223785,27.261209],[112.233085,27.265388],[112.239048,27.287822],[112.254912,27.295684],[112.256116,27.310691],[112.267275,27.305084],[112.279857,27.31223],[112.287844,27.328939],[112.282593,27.337073],[112.299715,27.358723],[112.309125,27.360426],[112.312133,27.367074],[112.321543,27.363998],[112.331061,27.370206],[112.339267,27.365921],[112.358742,27.362459],[112.370503,27.363888],[112.368151,27.356086],[112.408523,27.36147],[112.432374,27.354218],[112.438118,27.344602],[112.459891,27.355152],[112.471871,27.372404],[112.485712,27.359877],[112.489596,27.371909],[112.49988,27.374931],[112.499005,27.397727],[112.50453,27.403988],[112.51279,27.403164],[112.508359,27.417004],[112.522418,27.420464],[112.521981,27.429194],[112.500974,27.445831],[112.480952,27.453132],[112.47023,27.461916],[112.460164,27.490456],[112.446379,27.491499],[112.429639,27.499785],[112.435985,27.514546],[112.427123,27.526067],[112.417604,27.527713],[112.406007,27.524092],[112.399606,27.510266],[112.401193,27.503736],[112.391948,27.499731],[112.393479,27.492542],[112.373731,27.48656],[112.365799,27.480907],[112.348129,27.488206],[112.346105,27.496273],[112.333851,27.495725],[112.328709,27.490511],[112.321652,27.496493],[112.306389,27.492816],[112.301411,27.503188],[112.308578,27.53457],[112.325317,27.556182],[112.332429,27.569947],[112.334289,27.581408],[112.330788,27.602517],[112.298019,27.620991],[112.283906,27.633652],[112.281882,27.643298],[112.288884,27.646915],[112.313501,27.651025],[112.315142,27.664285],[112.320613,27.675298],[112.315744,27.685871],[112.304201,27.697868],[112.290525,27.7057],[112.268534,27.700935],[112.243369,27.707727],[112.240853,27.691075],[112.230623,27.685871],[112.222636,27.671517],[112.216564,27.675846],[112.2071,27.670531],[112.206827,27.651627],[112.199387,27.654313],[112.176083,27.650203],[112.166673,27.660066],[112.154857,27.64949],[112.145776,27.665162],[112.137953,27.666258],[112.134616,27.654696],[112.124879,27.646147],[112.11722,27.645435],[112.113664,27.653436],[112.104255,27.653381],[112.091235,27.642366],[112.078052,27.645764],[112.067001,27.658477],[112.07094,27.6696],[112.05803,27.680393],[112.048183,27.674038],[112.048785,27.688336],[112.052997,27.690527],[112.045338,27.706303],[112.053489,27.714135],[112.071761,27.720652],[112.083303,27.71523],[112.092111,27.716325],[112.081826,27.721747],[112.087187,27.733739],[112.099113,27.73467],[112.100699,27.722295],[112.106389,27.717147],[112.110929,27.738722],[112.130623,27.747428],[112.11268,27.761991],[112.098675,27.765001],[112.097745,27.776551],[112.106498,27.790617],[112.101246,27.807363],[112.087023,27.81382],[112.069901,27.80397],[112.04687,27.817048],[112.040524,27.839534],[112.026957,27.835157],[112.014813,27.847083],[112.012296,27.87864],[111.999714,27.907837],[111.99025,27.940962],[111.982264,27.954351],[111.964156,27.965171],[111.951246,27.987079],[111.936311,27.991231],[111.926848,27.980851],[111.912624,27.973803],[111.900097,27.981343],[111.908303,28.000189],[111.896377,28.00871],[111.902613,28.021982],[111.891837,28.026951],[111.870173,28.026678],[111.858193,28.030938],[111.848346,28.028644],[111.838335,28.019961],[111.823401,28.022582],[111.796103,28.00516],[111.793094,27.989701],[111.778871,27.996639],[111.779418,28.007072],[111.773893,28.010676],[111.765633,28.006143],[111.747963,28.003904],[111.743368,27.994235],[111.726792,27.983474],[111.71514,27.993361],[111.706114,27.99063],[111.697689,27.994181],[111.688499,27.99063],[111.684888,28.002975],[111.691289,28.009912],[111.683466,28.0145],[111.68549,28.040493],[111.672853,28.036453],[111.662952,28.014227],[111.652284,28.015756],[111.651573,28.021163],[111.662788,28.024712],[111.651518,28.026241],[111.634286,28.015319],[111.621704,28.016083],[111.601682,28.034542],[111.589811,28.027115],[111.588991,28.018596],[111.599768,28.009693],[111.592766,28.006471],[111.583794,27.994454],[111.55026,27.974841],[111.529527,27.986587],[111.542054,27.994126],[111.551409,27.991886],[111.564264,28.018104],[111.575807,28.018869],[111.567547,28.032903],[111.543859,28.020398],[111.540687,28.035579],[111.543914,28.047537],[111.534013,28.054143],[111.527886,28.049393],[111.514702,28.06528],[111.506879,28.053324],[111.522032,28.044479],[111.524439,28.031211],[111.517875,28.030992],[111.501956,28.04164],[111.494789,28.037873],[111.49189,28.066863],[111.493312,28.074887],[111.510982,28.090279],[111.500424,28.092626],[111.499877,28.101412],[111.482645,28.120402],[111.481387,28.138351],[111.49096,28.153024],[111.485763,28.159515],[111.495719,28.189945],[111.483137,28.204176],[111.477448,28.199323],[111.450095,28.187382],[111.445336,28.189509],[111.448454,28.202867],[111.434833,28.208101],[111.398016,28.180021],[111.386911,28.17893],[111.382918,28.196324],[111.352064,28.199051],[111.341835,28.193162],[111.332097,28.195943],[111.337732,28.20592],[111.32597,28.226526],[111.314373,28.234211],[111.296047,28.225436],[111.285215,28.214806],[111.279034,28.191036],[111.257753,28.167532],[111.235653,28.154115],[111.225149,28.161479],[111.216014,28.159297],[111.186528,28.160606],[111.189537,28.154988],[111.160926,28.122857],[111.151571,28.122966],[111.140959,28.103431],[111.137895,28.085968],[111.123289,28.068774],[111.114208,28.064134],[111.118475,28.050158],[111.093803,28.02717],[111.097906,28.006799],[111.081987,27.995601],[111.070608,27.995273],[111.063223,28.007236],[111.04156,28.022309],[111.03505,28.033723],[111.022031,28.027497],[111.013223,28.028917],[110.9804,28.029081],[110.971155,28.002757],[110.990958,27.992979],[111.000532,27.992214],[110.987402,27.972875],[110.966669,27.949269],[110.970772,27.925276],[110.9804,27.919973],[110.973945,27.910899],[110.944787,27.896247],[110.929689,27.879077],[110.922358,27.863273],[110.912785,27.864257],[110.898507,27.855998],[110.894514,27.849872],[110.882096,27.850474],[110.87668,27.846371],[110.837183,27.849216],[110.806548,27.864257],[110.791614,27.85567],[110.78587,27.832914],[110.767763,27.795433],[110.785706,27.782681],[110.795717,27.758158],[110.811472,27.757775],[110.830345,27.714956],[110.837511,27.681489],[110.849163,27.675791],[110.859995,27.677215],[110.86831,27.672887],[110.869185,27.655463],[110.882916,27.650696],[110.91749,27.656395],[110.945717,27.653819],[110.983792,27.660121],[110.994733,27.652395],[110.998453,27.639352],[110.994076,27.630144],[111.008081,27.625869],[111.02575,27.63568],[111.040247,27.631843],[111.059941,27.631295],[111.070827,27.620607],[111.07411,27.591442],[111.080291,27.588756],[111.106932,27.590729],[111.116287,27.577186],[111.130237,27.581408],[111.143147,27.578008],[111.150094,27.582176],[111.163442,27.576473],[111.169515,27.562653],[111.182151,27.56375],[111.182863,27.557005],[111.197414,27.549161],[111.204143,27.552781],[111.220773,27.551739],[111.223782,27.536161],[111.244624,27.52508],[111.256112,27.542799],[111.270718,27.541756],[111.278377,27.555798],[111.300861,27.567096],[111.322141,27.546858],[111.349822,27.537039],[111.357097,27.522885],[111.367765,27.524915],[111.376518,27.532815],[111.374603,27.542963],[111.388388,27.544938],[111.403979,27.557388],[111.414373,27.575212],[111.430347,27.59062],[111.441944,27.597473],[111.457918,27.595445],[111.468257,27.579599],[111.477831,27.578666],[111.489373,27.594238],[111.522251,27.605532],[111.542656,27.609644],[111.553597,27.626034],[111.560927,27.630583],[111.567984,27.627075],[111.568148,27.61688],[111.574056,27.607725],[111.589046,27.606574],[111.594625,27.582944],[111.6077,27.57587],[111.615577,27.566163],[111.620665,27.571757],[111.612405,27.580695],[111.625479,27.575212],[111.635162,27.578776],[111.641398,27.574663],[111.635599,27.562379],[111.625917,27.556127],[111.630621,27.553056],[111.639866,27.559198],[111.641672,27.54779],[111.652831,27.540111],[111.650096,27.534022],[111.638663,27.537917],[111.643914,27.520142],[111.654035,27.514765],[111.668915,27.537149],[111.67537,27.537149],[111.690742,27.523708],[111.692985,27.533857],[111.717766,27.516576],[111.73095,27.518222],[111.744079,27.499401],[111.78746,27.494627],[111.790195,27.470479],[111.796377,27.468173],[111.803598,27.474815],[111.810764,27.471357],[111.813609,27.45434],[111.819517,27.44929],[111.835162,27.44605],[111.840195,27.456646],[111.855294,27.461147],[111.882537,27.438364],[111.892766,27.426833],[111.912843,27.410304],[111.907318,27.39542],[111.909451,27.388939],[111.940852,27.369217],[111.970502,27.357514],[111.990305,27.341579],[111.98571,27.332731],[111.990797,27.317342],[112.01804,27.317562],[112.025152,27.3036],[112.041071,27.289142],[112.051301,27.292385],[112.062406,27.285843],[112.065196,27.250815],[112.069244,27.235909],[112.068424,27.218636],[112.085327,27.204002],[112.092165,27.205652]]]]}},{"type":"Feature","properties":{"adcode":433100,"name":"湘西土家族苗族自治州","center":[109.739735,28.314296],"centroid":[109.731854,28.694703],"childrenNum":8,"level":"city","parent":{"adcode":430000},"subFeatureIndex":13,"acroutes":[100000,430000]},"geometry":{"type":"MultiPolygon","coordinates":[[[[109.418415,27.721364],[109.426402,27.738941],[109.442704,27.74918],[109.451128,27.765056],[109.461522,27.773322],[109.454465,27.794886],[109.461358,27.803423],[109.475144,27.804736],[109.479192,27.799428],[109.47673,27.788702],[109.485866,27.787881],[109.492649,27.795762],[109.507255,27.802821],[109.51196,27.80014],[109.52126,27.812507],[109.532802,27.811522],[109.533021,27.795871],[109.540953,27.786513],[109.549761,27.786184],[109.559662,27.799209],[109.573776,27.808895],[109.585975,27.802766],[109.59626,27.804627],[109.603372,27.79817],[109.613383,27.815625],[109.626676,27.817103],[109.623175,27.826623],[109.636796,27.827334],[109.647409,27.834993],[109.647628,27.843308],[109.640516,27.856053],[109.643142,27.861905],[109.63696,27.876015],[109.622518,27.878859],[109.622737,27.89324],[109.63045,27.90997],[109.649871,27.903956],[109.661523,27.919536],[109.670713,27.921668],[109.681982,27.935934],[109.696096,27.936972],[109.711249,27.949815],[109.719127,27.952657],[109.713383,27.96752],[109.719783,27.98178],[109.733077,27.987407],[109.730834,28.00516],[109.736031,28.012424],[109.732201,28.02362],[109.752442,28.02149],[109.790134,28.029736],[109.784718,28.021436],[109.784444,28.006744],[109.77591,27.999097],[109.792924,27.973913],[109.797847,27.979322],[109.816118,27.980906],[109.833186,27.986205],[109.842158,27.984402],[109.837453,27.975005],[109.857147,27.970908],[109.876841,27.956318],[109.882585,27.946919],[109.909335,27.93741],[109.914368,27.951236],[109.933624,27.959269],[109.947793,27.956865],[109.951513,27.94834],[109.957913,27.951673],[109.958406,27.961182],[109.970277,27.956865],[109.974106,27.93812],[109.984117,27.945935],[110.001732,27.936153],[110.000364,27.919755],[110.016064,27.908603],[110.02252,27.908001],[110.044292,27.918661],[110.053975,27.933146],[110.047848,27.950034],[110.062454,27.959269],[110.06962,27.96834],[110.09927,27.977082],[110.110321,27.988554],[110.111141,28.005542],[110.117706,28.016411],[110.128592,28.024821],[110.122192,28.040002],[110.130835,28.03962],[110.137509,28.047264],[110.137454,28.057801],[110.124489,28.065771],[110.116284,28.075542],[110.111743,28.090934],[110.123176,28.093663],[110.147301,28.092189],[110.166776,28.103104],[110.166338,28.110635],[110.151787,28.120893],[110.154905,28.13044],[110.177881,28.133987],[110.182258,28.145715],[110.169183,28.155588],[110.174544,28.165733],[110.194293,28.173477],[110.202006,28.187873],[110.191448,28.201231],[110.216667,28.204394],[110.223013,28.198069],[110.235923,28.197688],[110.24298,28.207229],[110.240299,28.230832],[110.226514,28.24086],[110.208844,28.243803],[110.205999,28.252523],[110.186525,28.259389],[110.175037,28.280529],[110.185759,28.285705],[110.178428,28.3027],[110.1781,28.316426],[110.185047,28.333144],[110.203045,28.339787],[110.211525,28.346974],[110.205835,28.362599],[110.190409,28.363252],[110.179796,28.37648],[110.170058,28.378058],[110.152061,28.391719],[110.141448,28.383338],[110.125802,28.402495],[110.111743,28.415935],[110.110375,28.425239],[110.114205,28.442538],[110.10299,28.45271],[110.109227,28.463642],[110.127389,28.459944],[110.126349,28.44863],[110.138111,28.447706],[110.141667,28.456517],[110.15775,28.461412],[110.163603,28.467558],[110.148614,28.483654],[110.150857,28.527798],[110.167104,28.535027],[110.165463,28.556982],[110.167542,28.574749],[110.172465,28.584256],[110.185868,28.582735],[110.188603,28.574966],[110.207531,28.575129],[110.211087,28.566545],[110.224216,28.563285],[110.236634,28.57339],[110.229905,28.587569],[110.224544,28.612066],[110.230835,28.615922],[110.212072,28.625697],[110.218582,28.644158],[110.228647,28.653116],[110.243363,28.644755],[110.244019,28.658164],[110.251076,28.659956],[110.257695,28.672386],[110.270278,28.671409],[110.273724,28.689428],[110.271536,28.700716],[110.28554,28.743521],[110.283844,28.762721],[110.288275,28.767439],[110.310868,28.757135],[110.33089,28.760063],[110.340409,28.769825],[110.342597,28.782025],[110.340464,28.80176],[110.344785,28.820732],[110.365901,28.846095],[110.377608,28.850268],[110.396317,28.864192],[110.390409,28.881149],[110.384665,28.885428],[110.358735,28.891224],[110.364807,28.907959],[110.361087,28.927454],[110.331,28.941152],[110.314588,28.938336],[110.308133,28.944292],[110.306492,28.958258],[110.319184,28.967297],[110.318965,28.973143],[110.33193,28.981315],[110.327991,28.983858],[110.346208,29.011129],[110.347357,29.019406],[110.341613,29.02725],[110.340354,29.041313],[110.323122,29.041746],[110.313987,29.035905],[110.305289,29.038609],[110.299599,29.057159],[110.304194,29.091331],[110.284446,29.085438],[110.273505,29.074409],[110.261962,29.069542],[110.249654,29.076896],[110.250529,29.093655],[110.264041,29.110142],[110.261634,29.1196],[110.238986,29.122248],[110.216722,29.129112],[110.223997,29.136461],[110.215901,29.136083],[110.205562,29.151968],[110.203921,29.161044],[110.189643,29.162827],[110.179085,29.153967],[110.164861,29.165528],[110.158187,29.165204],[110.140408,29.14543],[110.128428,29.136407],[110.119128,29.141216],[110.099872,29.139595],[110.089041,29.151266],[110.090518,29.167311],[110.084828,29.184434],[110.070058,29.211867],[110.073176,29.225636],[110.080616,29.2326],[110.082859,29.251223],[110.103537,29.253436],[110.113548,29.279017],[110.112564,29.289701],[110.097192,29.308853],[110.068417,29.323795],[110.049216,29.314571],[110.016338,29.288298],[110.001568,29.29542],[109.975528,29.299142],[109.951294,29.318077],[109.936141,29.325143],[109.952935,29.333827],[109.960375,29.341269],[109.954795,29.358147],[109.945167,29.369901],[109.952662,29.383486],[109.945276,29.398417],[109.935867,29.434414],[109.925637,29.444435],[109.908405,29.441741],[109.828919,29.373297],[109.821206,29.388661],[109.79451,29.411675],[109.795276,29.417117],[109.808241,29.427086],[109.801895,29.448852],[109.788383,29.463935],[109.779357,29.478046],[109.778755,29.486878],[109.769455,29.491779],[109.76579,29.500017],[109.752934,29.509062],[109.740954,29.534256],[109.734663,29.540984],[109.738766,29.547604],[109.74916,29.549487],[109.760101,29.561649],[109.782366,29.576608],[109.768525,29.587314],[109.764915,29.596136],[109.769565,29.606518],[109.761687,29.615177],[109.745713,29.615339],[109.72695,29.607863],[109.715571,29.613133],[109.701567,29.608239],[109.678755,29.60797],[109.663492,29.599687],[109.650637,29.611574],[109.652114,29.623782],[109.634553,29.625234],[109.609444,29.634483],[109.575417,29.627869],[109.575636,29.619856],[109.558678,29.607056],[109.550417,29.612811],[109.531107,29.615607],[109.529028,29.626041],[109.5165,29.625987],[109.514312,29.618028],[109.520275,29.608454],[109.514531,29.600278],[109.501457,29.605442],[109.495931,29.598718],[109.503645,29.59775],[109.504028,29.588605],[109.497627,29.568107],[109.488656,29.553201],[109.479903,29.55277],[109.467047,29.559981],[109.46185,29.554277],[109.458623,29.530542],[109.465242,29.515577],[109.458568,29.513208],[109.447627,29.520745],[109.446533,29.528766],[109.430997,29.529035],[109.431325,29.505294],[109.440625,29.493179],[109.434881,29.489032],[109.418305,29.498025],[109.40999,29.490594],[109.412835,29.484724],[109.405121,29.468729],[109.417102,29.454778],[109.403152,29.446159],[109.404793,29.434414],[109.394946,29.439694],[109.3729,29.424985],[109.368579,29.411351],[109.385264,29.393566],[109.382036,29.382893],[109.391445,29.372219],[109.376784,29.376532],[109.368798,29.382893],[109.347408,29.373782],[109.343962,29.369415],[109.340132,29.335984],[109.344126,29.323201],[109.344126,29.306425],[109.352277,29.305239],[109.352167,29.284629],[109.326839,29.260669],[109.315077,29.252087],[109.286084,29.242047],[109.261357,29.227795],[109.257856,29.222612],[109.276073,29.200312],[109.27104,29.183245],[109.273885,29.172551],[109.261467,29.161044],[109.264038,29.144026],[109.277167,29.134083],[109.274158,29.12214],[109.255942,29.123221],[109.245329,29.115114],[109.232583,29.119438],[109.225963,29.113277],[109.234497,29.096845],[109.235044,29.088844],[109.256106,29.087168],[109.266226,29.079545],[109.287834,29.071002],[109.301182,29.070678],[109.312233,29.066352],[109.319618,29.042557],[109.312123,29.035147],[109.304848,29.020813],[109.29429,29.014537],[109.29243,28.987646],[109.284826,28.972601],[109.272353,28.970924],[109.26174,28.953007],[109.255395,28.926154],[109.256872,28.907743],[109.240405,28.892741],[109.235427,28.881691],[109.23406,28.863813],[109.242648,28.85108],[109.239749,28.830108],[109.245821,28.812981],[109.246423,28.801652],[109.241882,28.794279],[109.241281,28.776495],[109.261303,28.774922],[109.256215,28.765595],[109.279629,28.756592],[109.28116,28.750572],[109.292594,28.750247],[109.299979,28.744931],[109.299158,28.736741],[109.288217,28.727302],[109.294673,28.71911],[109.284935,28.713847],[109.271478,28.698979],[109.265023,28.699468],[109.252933,28.691545],[109.266171,28.680202],[109.270876,28.671789],[109.240679,28.655776],[109.22476,28.650673],[109.202933,28.637968],[109.19314,28.636231],[109.181434,28.621733],[109.186357,28.610654],[109.201456,28.598433],[109.235482,28.619615],[109.249377,28.608644],[109.258896,28.605603],[109.278042,28.612337],[109.287014,28.626837],[109.300143,28.626457],[109.306653,28.620646],[109.30906,28.607612],[109.304465,28.602779],[109.32022,28.579801],[109.304738,28.579041],[109.29511,28.567305],[109.288929,28.546331],[109.274158,28.538886],[109.274705,28.524809],[109.28034,28.520406],[109.27197,28.513992],[109.273994,28.488113],[109.266335,28.481805],[109.26081,28.46473],[109.26464,28.457659],[109.260154,28.451296],[109.258294,28.428993],[109.264366,28.404399],[109.264694,28.392481],[109.276565,28.376861],[109.288381,28.374303],[109.28778,28.36445],[109.268578,28.338099],[109.275088,28.312668],[109.297572,28.292787],[109.294946,28.278568],[109.306379,28.274209],[109.314913,28.276389],[109.340953,28.293713],[109.363108,28.282981],[109.352167,28.268543],[109.359498,28.265873],[109.365898,28.274209],[109.376894,28.276934],[109.399651,28.269306],[109.387999,28.268107],[109.367649,28.255248],[109.372846,28.248381],[109.367266,28.239062],[109.356762,28.233503],[109.359552,28.220421],[109.345767,28.206683],[109.34046,28.190381],[109.34325,28.173586],[109.341828,28.162133],[109.335811,28.158206],[109.338163,28.141788],[109.328097,28.12684],[109.325417,28.115218],[109.314366,28.103923],[109.312123,28.083511],[109.304957,28.076416],[109.298721,28.032521],[109.305887,28.030009],[109.311522,28.037982],[109.325253,28.042787],[109.334552,28.062223],[109.347025,28.060367],[109.370548,28.046063],[109.379137,28.033067],[109.364859,28.008819],[109.344673,28.006198],[109.321587,27.991777],[109.320165,27.970962],[109.307145,27.968012],[109.301784,27.95834],[109.313819,27.93331],[109.314859,27.918115],[109.311905,27.907783],[109.320603,27.895591],[109.317758,27.88553],[109.321916,27.867976],[109.337561,27.869507],[109.326839,27.858624],[109.345548,27.840737],[109.340242,27.821425],[109.342649,27.800742],[109.331215,27.791602],[109.341062,27.790234],[109.333021,27.782791],[109.338163,27.775894],[109.34987,27.771077],[109.364312,27.759801],[109.362999,27.745019],[109.377988,27.73801],[109.365898,27.722185],[109.392375,27.726347],[109.400307,27.720268],[109.412616,27.725361],[109.418415,27.721364]]]]}}]} \ No newline at end of file diff --git a/examples/data/indoor-3d-map.json b/examples/data/indoor-3d-map.json new file mode 100644 index 00000000000..ac81fd8ca7c --- /dev/null +++ b/examples/data/indoor-3d-map.json @@ -0,0 +1,685 @@ +{ + "features": [ + { + "type": "Feature", + "properties": { + "level": 1, + "name": "Bird Exhibit", + "height": 0, + "base_height": 0, + "color": "orange" + }, + "geometry": { + "coordinates": [ + [ + [-87.618312, 41.866282], + [-87.61832, 41.866674], + [-87.618087, 41.866676], + [-87.618087, 41.866661], + [-87.617423, 41.86667], + [-87.617416, 41.8663], + [-87.618312, 41.866282] + ] + ], + "type": "Polygon" + }, + "id": "06e8fa0b3f851e3ae0e1da5fc17e111e" + }, + { + "type": "Feature", + "properties": { + "level": 1, + "name": "Bird Exhibit", + "height": 40, + "base_height": 0, + "color": "grey" + }, + "geometry": { + "coordinates": [ + [ + [-87.617808, 41.866266], + [-87.617806, 41.866293], + [-87.617415, 41.866298], + [-87.617424, 41.866671], + [-87.617382, 41.866669], + [-87.617371, 41.866274], + [-87.617808, 41.866266] + ] + ], + "type": "Polygon" + }, + "id": "08a10ab2bf15c4d14669b588062f7f08" + }, + { + "type": "Feature", + "properties": { + "level": 1, + "name": "East Hallway", + "base_height": 0, + "height": 0, + "color": "indigo" + }, + "geometry": { + "coordinates": [ + [ + [-87.616704, 41.866141], + [-87.616707, 41.866338], + [-87.61572, 41.866355], + [-87.61572, 41.866148], + [-87.616704, 41.866141] + ] + ], + "type": "Polygon" + }, + "id": "09ead44537d94ece576c7bc001c33e53" + }, + { + "type": "Feature", + "properties": { + "level": 1, + "name": "East Entrance", + "base_height": 0, + "height": 0, + "color": "violet" + }, + "geometry": { + "coordinates": [ + [ + [-87.61544, 41.866149], + [-87.615449, 41.866358], + [-87.615721, 41.866355], + [-87.61572, 41.866143], + [-87.61544, 41.866149] + ] + ], + "type": "Polygon" + }, + "id": "12251ebf764b36cf3b8c5ad42e2deb29" + }, + { + "type": "Feature", + "properties": { + "height": 0, + "base_height": 0, + "level": 1, + "name": "Under the Earth", + "color": "red" + }, + "geometry": { + "coordinates": [ + [ + [-87.616701, 41.865816], + [-87.616705, 41.866115], + [-87.615712, 41.866125], + [-87.615706, 41.865802], + [-87.615936, 41.865801], + [-87.615938, 41.865824], + [-87.616701, 41.865816] + ] + ], + "type": "Polygon" + }, + "id": "1ce4f8c186a40b9927006644e27bfd69" + }, + { + "type": "Feature", + "properties": { + "level": 1, + "name": "Atrium", + "base_height": 0, + "height": 0, + "color": "yellow" + }, + "geometry": { + "coordinates": [ + [ + [-87.617365, 41.865799], + [-87.6167, 41.865815], + [-87.616718, 41.866672], + [-87.617384, 41.86667], + [-87.617365, 41.865799] + ] + ], + "type": "Polygon" + }, + "id": "369f5d8865e677120b7576b1de6082eb" + }, + { + "type": "Feature", + "properties": { + "level": 1, + "name": "Ancient Egypt", + "height": 0, + "base_height": 0, + "color": "blue" + }, + "geometry": { + "coordinates": [ + [ + [-87.61807, 41.865761], + [-87.618299, 41.865758], + [-87.618307, 41.866139], + [-87.617407, 41.86615], + [-87.617399, 41.865799], + [-87.61807, 41.865789], + [-87.61807, 41.865761] + ] + ], + "type": "Polygon" + }, + "id": "3e9f198afe6d7dff01ac81c6eaa511fb" + }, + { + "type": "Feature", + "properties": { + "level": 1, + "name": "West Arch", + "height": 40, + "base_height": 30, + "color": "grey" + }, + "geometry": { + "coordinates": [ + [ + [-87.617424, 41.86667], + [-87.617384, 41.86667], + [-87.617365, 41.865799], + [-87.617405, 41.865799], + [-87.617424, 41.86667] + ] + ], + "type": "Polygon" + }, + "id": "402706f28b793d27c78d9615fff747f2" + }, + { + "type": "Feature", + "properties": { + "level": 1, + "name": "Bird Exhibit", + "height": 40, + "base_height": 0, + "color": "grey" + }, + "geometry": { + "coordinates": [ + [ + [-87.618312, 41.866283], + [-87.61797, 41.866288], + [-87.617972, 41.866265], + [-87.618312, 41.866259], + [-87.618312, 41.866283] + ] + ], + "type": "Polygon" + }, + "id": "43e1e2fc8399dee075ad59764f2a2878" + }, + { + "type": "Feature", + "properties": { + "name": "Arch", + "level": 1, + "color": "grey", + "base_height": 30, + "height": 40 + }, + "geometry": { + "coordinates": [ + [ + [-87.617971, 41.866291], + [-87.617973, 41.866265], + [-87.617805, 41.866267], + [-87.617806, 41.866294], + [-87.617971, 41.866291] + ] + ], + "type": "Polygon" + }, + "id": "4528ad9b9264cbec65bb2e55ac0012c1" + }, + { + "type": "Feature", + "properties": { + "level": 1, + "color": "grey", + "base_height": 30, + "height": 40, + "name": "Arch" + }, + "geometry": { + "coordinates": [ + [ + [-87.617979, 41.866167], + [-87.617797, 41.866168], + [-87.617799, 41.866145], + [-87.617976, 41.866144], + [-87.617979, 41.866167] + ] + ], + "type": "Polygon" + }, + "id": "4be6817c3b595042c8d971eebd0c4fd3" + }, + { + "type": "Feature", + "properties": { + "name": "Kids Zone", + "level": 1, + "base_height": 0, + "height": 0, + "color": "green" + }, + "geometry": { + "coordinates": [ + [ + [-87.616718, 41.866675], + [-87.616709, 41.866371], + [-87.615725, 41.866381], + [-87.615732, 41.866711], + [-87.61596, 41.866711], + [-87.61596, 41.866688], + [-87.616718, 41.866675] + ] + ], + "type": "Polygon" + }, + "id": "5775eba03674ea1cb3550ffb38321432" + }, + { + "type": "Feature", + "properties": { + "level": 1, + "color": "grey", + "name": "Arch", + "height": 40, + "base_height": 30 + }, + "geometry": { + "coordinates": [ + [ + [-87.616286, 41.866119], + [-87.616286, 41.866144], + [-87.616089, 41.866149], + [-87.616086, 41.86612], + [-87.616286, 41.866119] + ] + ], + "type": "Polygon" + }, + "id": "598832b1512dc9facc855c5367251531" + }, + { + "type": "Feature", + "properties": { + "level": 1, + "name": "Arch", + "color": "grey", + "height": 40, + "base_height": 30 + }, + "geometry": { + "coordinates": [ + [ + [-87.616287, 41.866343], + [-87.616288, 41.866374], + [-87.616076, 41.866378], + [-87.616077, 41.866347], + [-87.616287, 41.866343] + ] + ], + "type": "Polygon" + }, + "id": "59ed13d4411ff5f88714d9af539788d2" + }, + { + "type": "Feature", + "properties": { + "level": 1, + "color": "grey", + "name": "center_arch", + "base_height": 30, + "height": 40 + }, + "geometry": { + "coordinates": [ + [ + [-87.61737, 41.866198], + [-87.617372, 41.86624], + [-87.616708, 41.866243], + [-87.616708, 41.866203], + [-87.61737, 41.866198] + ] + ], + "type": "Polygon" + }, + "id": "67f8952a18dfe21ee0744a3e86bc41d8" + }, + { + "type": "Feature", + "properties": { + "level": 1, + "name": "Kids Zone", + "height": 0, + "base_height": 40, + "color": "grey" + }, + "geometry": { + "coordinates": [ + [ + [-87.615719, 41.866354], + [-87.615718, 41.866381], + [-87.616077, 41.866378], + [-87.616077, 41.866347], + [-87.615719, 41.866354] + ] + ], + "type": "Polygon" + }, + "id": "6bb2c92386bcf4678113d6b3e400ae3b" + }, + { + "type": "Feature", + "properties": { + "level": 1, + "name": "Under the Earth", + "height": 40, + "base_height": 0, + "color": "grey" + }, + "geometry": { + "coordinates": [ + [ + [-87.616089, 41.866149], + [-87.616089, 41.866119], + [-87.615711, 41.866124], + [-87.615713, 41.866147], + [-87.616089, 41.866149] + ] + ], + "type": "Polygon" + }, + "id": "844c87987089df6b9db3923f6a00e4d6" + }, + { + "type": "Feature", + "properties": { + "level": 1, + "name": "Under the Earth", + "height": 40, + "base_height": 0, + "color": "grey" + }, + "geometry": { + "coordinates": [ + [ + [-87.616707, 41.866115], + [-87.616286, 41.866119], + [-87.616285, 41.866144], + [-87.616705, 41.866141], + [-87.616707, 41.866115] + ] + ], + "type": "Polygon" + }, + "id": "85547a1ecdbd2ca1fdc6324aea3c6b70" + }, + { + "type": "Feature", + "properties": { + "level": 1, + "name": "North Entrance", + "height": 0, + "base_height": 0, + "color": "grey" + }, + "geometry": { + "coordinates": [ + [ + [-87.617386, 41.86667], + [-87.617388, 41.866786], + [-87.617228, 41.866786], + [-87.617226, 41.866848], + [-87.616867, 41.866849], + [-87.616868, 41.866791], + [-87.616718, 41.866791], + [-87.616718, 41.866672], + [-87.617386, 41.86667] + ] + ], + "type": "Polygon" + }, + "id": "91ab1ee01729c33568c7b57eb258e699" + }, + { + "type": "Feature", + "properties": { + "level": 1, + "name": "Ancient Egypt", + "height": 40, + "base_height": 0, + "color": "grey" + }, + "geometry": { + "coordinates": [ + [ + [-87.617394, 41.865799], + [-87.617405, 41.86615], + [-87.617802, 41.866147], + [-87.6178, 41.866167], + [-87.617369, 41.866172], + [-87.617364, 41.865799], + [-87.617394, 41.865799] + ] + ], + "type": "Polygon" + }, + "id": "943171d55d207024791e15294def7e8f" + }, + { + "type": "Feature", + "properties": { + "level": 1, + "name": "Ancient Egypt", + "height": 40, + "base_height": 0, + "color": "grey" + }, + "geometry": { + "coordinates": [ + [ + [-87.617976, 41.866166], + [-87.617976, 41.866143], + [-87.618309, 41.866139], + [-87.618309, 41.866161], + [-87.617976, 41.866166] + ] + ], + "type": "Polygon" + }, + "id": "a37230898905988cab9b72927dc99258" + }, + { + "type": "Feature", + "properties": { + "name": "West Hallway", + "level": 1, + "base_height": 0, + "height": 0, + "color": "grey" + }, + "geometry": { + "coordinates": [ + [ + [-87.618309, 41.866161], + [-87.618312, 41.86626], + [-87.61737, 41.866272], + [-87.61737, 41.86617], + [-87.618309, 41.866161] + ] + ], + "type": "Polygon" + }, + "id": "c7cc79da8711d746985f23a9b22c1d5e" + }, + { + "type": "Feature", + "properties": { + "level": 1, + "name": "Kids Zone", + "height": 40, + "base_height": 0, + "color": "grey" + }, + "geometry": { + "coordinates": [ + [ + [-87.616286, 41.866343], + [-87.616286, 41.866374], + [-87.61671, 41.866371], + [-87.616708, 41.866338], + [-87.616286, 41.866343] + ] + ], + "type": "Polygon" + }, + "id": "cfbf2aee6a73a45c12e7fc7432d6009e" + }, + { + "type": "Feature", + "properties": { + "level": 1, + "name": "South Entrance", + "height": 0, + "base_height": 0, + "color": "teal" + }, + "geometry": { + "coordinates": [ + [ + [-87.617359, 41.865801], + [-87.617355, 41.865674], + [-87.617221, 41.865677], + [-87.617219, 41.86559], + [-87.616824, 41.865595], + [-87.616826, 41.86568], + [-87.616695, 41.865683], + [-87.6167, 41.865813], + [-87.617359, 41.865801] + ] + ], + "type": "Polygon" + }, + "id": "d71ab89467076ad023161c37f4ff0d5f" + }, + { + "type": "Feature", + "properties": { + "level": 1, + "name": "East Arch", + "height": 40, + "base_height": 30, + "color": "grey" + }, + "geometry": { + "coordinates": [ + [ + [-87.616688, 41.866675], + [-87.616716, 41.866675], + [-87.616699, 41.865814], + [-87.616665, 41.865814], + [-87.616688, 41.866675] + ] + ], + "type": "Polygon" + }, + "id": "dd2baec57e4079eb65dcae5be495da62" + }, + { + "type": "Feature", + "properties": { + "level": 1, + "name": "outer-walls", + "base_height": 0, + "height": 40, + "color": "grey" + }, + "geometry": { + "coordinates": [ + [ + [-87.618087, 41.86666], + [-87.618087, 41.866674], + [-87.618319, 41.866674], + [-87.618298, 41.865757], + [-87.618326, 41.865756], + [-87.618347, 41.866693], + [-87.618068, 41.866696], + [-87.618067, 41.866675], + [-87.61741, 41.866684], + [-87.617416, 41.866802], + [-87.617247, 41.866803], + [-87.617246, 41.866866], + [-87.616846, 41.866868], + [-87.616848, 41.866807], + [-87.61669, 41.866811], + [-87.616693, 41.866693], + [-87.615992, 41.866701], + [-87.615992, 41.866729], + [-87.615703, 41.866733], + [-87.615689, 41.866377], + [-87.615412, 41.866382], + [-87.615411, 41.866122], + [-87.615689, 41.866119], + [-87.615682, 41.865781], + [-87.615966, 41.865779], + [-87.615969, 41.865798], + [-87.616669, 41.865794], + [-87.616663, 41.865662], + [-87.6168, 41.865661], + [-87.616796, 41.865571], + [-87.61726, 41.865559], + [-87.617258, 41.865654], + [-87.617388, 41.865652], + [-87.617395, 41.865778], + [-87.618045, 41.865773], + [-87.618044, 41.865742], + [-87.618325, 41.865739], + [-87.618326, 41.865758], + [-87.61807, 41.865761], + [-87.61807, 41.865789], + [-87.617356, 41.8658], + [-87.617356, 41.865672], + [-87.617218, 41.865677], + [-87.617215, 41.86559], + [-87.616822, 41.865595], + [-87.616827, 41.86568], + [-87.616694, 41.865681], + [-87.616697, 41.865813], + [-87.615939, 41.865824], + [-87.615937, 41.8658], + [-87.615706, 41.865802], + [-87.615713, 41.866143], + [-87.615441, 41.86615], + [-87.61545, 41.866357], + [-87.615724, 41.866353], + [-87.615733, 41.866712], + [-87.615959, 41.86671], + [-87.615959, 41.866688], + [-87.616719, 41.866672], + [-87.61672, 41.866791], + [-87.616869, 41.86679], + [-87.616868, 41.86685], + [-87.617223, 41.866847], + [-87.617227, 41.866786], + [-87.617387, 41.866785], + [-87.617383, 41.86667], + [-87.618087, 41.86666] + ] + ], + "type": "Polygon" + }, + "id": "ef6512f46485e27963c248bcc945c3db" + } + ], + "type": "FeatureCollection" +} diff --git a/examples/data/nanjing-city.json b/examples/data/nanjing-city.json new file mode 100644 index 00000000000..9ac637be25d --- /dev/null +++ b/examples/data/nanjing-city.json @@ -0,0 +1 @@ +{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"id":611100790,"name":"浦口其它","longitude":118.55772865265,"latitude":31.987645655305,"unit_price":21747,"count":"22.26℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.622299,31.946889],[118.651727,31.979024],[118.60761258722,32.093276369469],[118.63513833466,32.1085476335],[118.65211412661,32.121203979744],[118.66132074171,32.126483825762],[118.66654,32.125296],[118.669667,32.124684],[118.672775,32.124684],[118.68340189757,32.124079434239],[118.68512533225,32.130701391203],[118.69021762996,32.135715974717],[118.69534654379,32.145562731002],[118.70214639163,32.151171604073],[118.690833,32.165187],[118.687869,32.170918],[118.690609,32.184159],[118.69042,32.18846],[118.730345,32.197982],[118.72399,32.176313],[118.73506166127,32.169432471485],[118.779287,32.16015],[118.77864,32.179894],[118.773609,32.196029],[118.754565,32.18949],[118.741774,32.174576],[118.739222,32.176135],[118.736563,32.180169],[118.739797,32.181177],[118.742708,32.185548],[118.741666,32.190437],[118.740624,32.195387],[118.743211,32.201223],[118.739474,32.206845],[118.73279,32.207914],[118.735449,32.215857],[118.73218,32.218881],[118.728946,32.22218],[118.72661,32.255897],[118.7108,32.254798],[118.682126,32.257241],[118.674221,32.241422],[118.657009,32.223005],[118.650326,32.21494],[118.645475,32.213902],[118.639834,32.210358],[118.637965,32.208922],[118.636348,32.207547],[118.63448,32.207792],[118.63254,32.208005],[118.626539,32.210847],[118.623521,32.210694],[118.615436,32.206814],[118.604548,32.20495],[118.596356,32.205775],[118.592224,32.2044],[118.585792,32.204859],[118.581767,32.208433],[118.575264,32.207028],[118.567826,32.202964],[118.561538,32.204248],[118.55798,32.205714],[118.555968,32.20437],[118.555213,32.201223],[118.550506,32.199665],[118.545871,32.19832],[118.538936,32.201864],[118.537643,32.201467],[118.53387,32.196151],[118.528983,32.193676],[118.523881,32.194929],[118.516047,32.199848],[118.512382,32.18952],[118.502824,32.182522],[118.503507,32.168127],[118.515796,32.142633],[118.510586,32.144314],[118.505735,32.146118],[118.502465,32.140064],[118.501603,32.137282],[118.504226,32.131197],[118.508466,32.126336],[118.50074,32.126825],[118.493841,32.125602],[118.489781,32.122513],[118.483565,32.123094],[118.480367,32.12181],[118.479792,32.119486],[118.48051,32.116244],[118.47972,32.114501],[118.47839,32.114134],[118.477348,32.113889],[118.47415,32.111343],[118.472165,32.109409],[118.471527,32.108231],[118.4708,32.107038],[118.469317,32.106641],[118.467179,32.107489],[118.465006,32.107099],[118.462059,32.105157],[118.460909,32.103414],[118.459454,32.103039],[118.456948,32.104263],[118.455537,32.103536],[118.454657,32.10063],[118.451073,32.100087],[118.447255,32.098007],[118.445863,32.096577],[118.445396,32.095323],[118.444021,32.094658],[118.44129,32.095201],[118.44006,32.09306],[118.437482,32.092371],[118.429361,32.092104],[118.426316,32.091706],[118.422201,32.094138],[118.418698,32.087041],[118.415491,32.086253],[118.411781,32.086131],[118.411871,32.08148],[118.410371,32.080547],[118.406634,32.083507],[118.401567,32.082819],[118.401603,32.080739],[118.403858,32.078046],[118.402394,32.073725],[118.401998,32.070963],[118.399438,32.067857],[118.396627,32.067513],[118.395378,32.068752],[118.393959,32.068477],[118.390626,32.065524],[118.400696,32.055927],[118.394183,32.04585],[118.392979,32.038818],[118.394911,32.03187],[118.402133,32.028197],[118.396295,32.017446],[118.398037,32.006222],[118.399771,31.994984],[118.397956,31.991837],[118.396088,31.988653],[118.387706,31.986371],[118.385919,31.98314],[118.388587,31.979173],[118.372777,31.958558],[118.371708,31.947559],[118.37116,31.942059],[118.37063,31.936574],[118.383377,31.929955],[118.39236,31.91585],[118.409374,31.919895],[118.426289,31.904064],[118.434733,31.902478],[118.445818,31.906133],[118.455394,31.895431],[118.48051,31.886452],[118.469551,31.873853],[118.474074,31.862749],[118.478723,31.860621],[118.482064,31.856243],[118.495907,31.849656],[118.506741,31.846827],[118.51161,31.855001],[118.516622,31.863251],[118.532271,31.884608],[118.556669,31.903355],[118.577348,31.927109],[118.601853,31.939305],[118.622299,31.946889]]]}},{"type":"Feature","properties":{"id":1100004207,"name":"江宁滨江","longitude":118.565242,"latitude":31.837904,"unit_price":15374,"count":"22.03℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.626416,31.868426],[118.637124,31.864562],[118.630656,31.85898],[118.62295,31.848824],[118.598928,31.823458],[118.584842,31.811185],[118.572482,31.798296],[118.548623,31.768953],[118.539568,31.772882],[118.530154,31.768032],[118.517865,31.771286],[118.509025,31.786449],[118.501839,31.783073],[118.488328,31.787493],[118.506941,31.846773],[118.581968,31.928204],[118.60484,31.904631],[118.599378,31.892124],[118.612026,31.872623],[118.617145,31.871431],[118.622859,31.8714],[118.626416,31.868426]]]}},{"type":"Feature","properties":{"id":611100520,"name":"江浦街道","longitude":118.65338431253,"latitude":32.060902198428,"unit_price":24213,"count":"31.41℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.649647,31.981672],[118.690179,32.046213],[118.68413523714,32.059600915116],[118.68112990268,32.086201029745],[118.63568951826,32.108155463682],[118.60846532736,32.092737720853],[118.649647,31.981672]]]}},{"type":"Feature","properties":{"id":611100524,"name":"奥体","longitude":118.72418921031,"latitude":31.990334637312,"unit_price":44160,"count":"25.47℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.730488,31.972399],[118.739694,31.980021],[118.747699,31.988479],[118.75136435539,31.992441240114],[118.753204,31.995694],[118.755792,31.999108],[118.757822,32.001834],[118.759834,32.004528],[118.75756512159,32.005520969958],[118.74761047075,32.010669378946],[118.73383219845,32.017425140244],[118.73731252455,32.022241594838],[118.73853985758,32.023999373655],[118.73962227556,32.028378974849],[118.72864909209,32.030780490071],[118.72213540418,32.034053965583],[118.71907505896,32.035866282407],[118.71171152838,32.02467287479],[118.71250860006,32.008841525355],[118.71016262313,31.999390989492],[118.70531491376,31.997305721448],[118.6890845508,31.992088027888],[118.68410508436,31.989712198148],[118.67872270585,31.986012422968],[118.67097093529,31.982322405587],[118.66498197284,31.977129985475],[118.652612,31.964576],[118.652037,31.961145],[118.661523,31.954895],[118.667704,31.954527],[118.672788,31.951939],[118.676758,31.954604],[118.680783,31.951096],[118.685346,31.950545],[118.692874,31.955339],[118.69909,31.957698],[118.706456,31.958786],[118.709529,31.960057],[118.712745,31.963082],[118.721494,31.961512],[118.724738,31.9637],[118.730488,31.972399]]]}},{"type":"Feature","properties":{"id":613000145,"name":"江心洲","longitude":118.70181907971,"latitude":32.025670552036,"unit_price":42315,"count":"21.36℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.67093091587,31.982340033095],[118.67871725626,31.986046824882],[118.68411262842,31.98975913179],[118.68909481422,31.992141697897],[118.70526719565,31.997362328361],[118.71010944424,31.999430976565],[118.71246742425,32.008876991358],[118.7116480385,32.024727191289],[118.71907514062,32.035959620393],[118.72252344507,32.033927980214],[118.72563662487,32.040898563593],[118.731682,32.046347],[118.729549,32.047972],[118.726846,32.049974],[118.729761,32.056336],[118.732689,32.062686],[118.733049,32.065386],[118.733853,32.069479],[118.734068,32.07307],[118.734136,32.074707],[118.734185,32.07634],[118.734261,32.07977],[118.734477,32.083205],[118.736301,32.094088],[118.735753,32.104809],[118.729661,32.096492],[118.724348,32.089594],[118.719565,32.083304],[118.712792,32.073957],[118.709522,32.069184],[118.706001,32.06461],[118.699299,32.055444],[118.696119,32.050716],[118.692634,32.046187],[118.67244,32.012529],[118.662541,31.995596],[118.657492,31.98719],[118.654707,31.982642],[118.6523,31.978874],[118.67093091587,31.982340033095]]]}},{"type":"Feature","properties":{"id":613000152,"name":"板桥","longitude":118.66134381649,"latitude":31.930745597213,"unit_price":23994,"count":"33.75℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.620605,31.934632],[118.615615,31.930251],[118.631389,31.923908],[118.633473,31.922482],[118.648601,31.915862],[118.650577,31.914391],[118.654422,31.912629],[118.653074,31.910498],[118.671615,31.902774],[118.673969,31.907878],[118.677639,31.908127],[118.681107,31.908418],[118.686658,31.903322],[118.697276,31.907989],[118.693916,31.913154],[118.686955,31.914203],[118.682535,31.91992],[118.685418,31.924341],[118.698264,31.931014],[118.69645601157,31.935627471179],[118.69181435732,31.941612881279],[118.68734792414,31.945302573162],[118.68315092711,31.948369456043],[118.685535,31.950012],[118.680478,31.950502],[118.67671025631,31.953805418348],[118.672555,31.95103],[118.669608,31.953274],[118.666491,31.954056],[118.66160619519,31.954458977775],[118.657248,31.956851],[118.654768,31.958613],[118.65237,31.959478],[118.651094,31.960865],[118.651714,31.96402],[118.648148,31.974213],[118.62264682323,31.946400205674],[118.610544,31.941312],[118.620605,31.934632]]]}},{"type":"Feature","properties":{"id":1100005820,"name":"岱山新城","longitude":118.699692,"latitude":31.944315,"unit_price":20167,"count":"23.15℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.683473,31.948406],[118.690205,31.952936],[118.693475,31.954958],[118.699224,31.957256],[118.70677,31.958298],[118.710076,31.959921],[118.712555,31.961974],[118.721179,31.961147],[118.727269,31.956643],[118.734043,31.953028],[118.73857,31.952446],[118.740798,31.934491],[118.732084,31.931763],[118.730432,31.937586],[118.724754,31.939792],[118.721808,31.934338],[118.699817,31.931886],[118.698452,31.931212],[118.696498,31.935705],[118.691971,31.94165],[118.683473,31.948406]]]}},{"type":"Feature","properties":{"id":1100003906,"name":"禄口","longitude":118.82982,"latitude":31.776052,"unit_price":16085,"count":"33.64℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.679711,31.908187],[118.680971,31.904964],[118.679139,31.901102],[118.679785,31.894174],[118.683989,31.883995],[118.683989,31.883995],[118.688337,31.873171],[118.688337,31.873202],[118.69308,31.857255],[118.694805,31.842532],[118.709247,31.819169],[118.718697,31.814751],[118.72998,31.81429],[118.749096,31.827238],[118.752653,31.82776],[118.75639,31.826686],[118.778237,31.824692],[118.796419,31.827514],[118.810145,31.831472],[118.811187,31.834171],[118.815068,31.829232],[118.817963,31.829387],[118.821628,31.830185],[118.825796,31.828406],[118.831976,31.829817],[118.847715,31.82994],[118.849511,31.825951],[118.857632,31.82681],[118.87202,31.824385],[118.885603,31.824446],[118.893436,31.826226],[118.904072,31.815855],[118.909929,31.785965],[118.900838,31.773379],[118.901521,31.765029],[118.906515,31.753209],[118.906228,31.740343],[118.939285,31.725878],[118.941836,31.720318],[118.948376,31.715404],[118.950209,31.70969],[118.956676,31.70412],[118.964725,31.699675],[118.981757,31.691195],[118.988065,31.675851],[118.993474,31.661727],[118.972597,31.653032],[118.96643,31.650462],[118.962318,31.680748],[118.943561,31.691441],[118.917726,31.685603],[118.898287,31.658375],[118.871841,31.652965],[118.851575,31.645372],[118.839358,31.633168],[118.810181,31.625666],[118.797533,31.641407],[118.800803,31.682254],[118.77044,31.680687],[118.762786,31.641007],[118.775901,31.604694],[118.773602,31.591807],[118.757253,31.593068],[118.739502,31.639316],[118.702672,31.630247],[118.65057,31.651336],[118.65154,31.656746],[118.646653,31.661602],[118.655313,31.671498],[118.64651,31.679304],[118.648306,31.688461],[118.667997,31.688461],[118.667386,31.69436],[118.672201,31.696203],[118.672453,31.703085],[118.683232,31.705358],[118.690562,31.712055],[118.687436,31.728795],[118.672309,31.734876],[118.654271,31.737241],[118.65251,31.744703],[118.644893,31.747897],[118.650606,31.754314],[118.644354,31.762911],[118.631023,31.762604],[118.623297,31.755726],[118.610146,31.760946],[118.586108,31.747682],[118.582802,31.747958],[118.579137,31.75327],[118.563219,31.734354],[118.555278,31.74369],[118.550103,31.737487],[118.537491,31.748511],[118.529874,31.749094],[118.535695,31.754775],[118.545684,31.755941],[118.548379,31.763648],[118.5542,31.765981],[118.548687,31.768684],[118.580215,31.805453],[118.608385,31.832331],[118.637778,31.864414],[118.651289,31.873982],[118.661026,31.885082],[118.668716,31.895996],[118.674106,31.907614],[118.679711,31.908187]]]}},{"type":"Feature","properties":{"id":613000153,"name":"江宁其它","longitude":118.886072,"latitude":31.850569,"unit_price":22333,"count":"32.79℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.595335,31.933812],[118.583118,31.928541],[118.599862,31.909915],[118.60191,31.907769],[118.60492,31.904566],[118.603563,31.901393],[118.601506,31.896634],[118.599512,31.892112],[118.605243,31.883213],[118.608064,31.878974],[118.610408,31.875248],[118.612088,31.872665],[118.617065,31.8715],[118.62294,31.871477],[118.626488,31.868495],[118.633791,31.865811],[118.637088,31.864623],[118.643401,31.869321],[118.650803,31.873982],[118.655079,31.878827],[118.658637,31.882568],[118.661152,31.885818],[118.663488,31.889251],[118.665751,31.892838],[118.667835,31.895536],[118.671988,31.902558],[118.674126,31.907539],[118.680055,31.908106],[118.681561,31.904672],[118.679765,31.900809],[118.680483,31.893697],[118.69348,31.858524],[118.694773,31.843188],[118.699887,31.835061],[118.706211,31.824753],[118.709506,31.81932],[118.718776,31.815148],[118.729879,31.814595],[118.749085,31.827436],[118.75275,31.827957],[118.755661,31.827021],[118.756271,31.833985],[118.756613,31.84644],[118.761859,31.857236],[118.766315,31.880097],[118.763476,31.881002],[118.757511,31.885202],[118.76759,31.884007],[118.782897,31.884283],[118.78994,31.883301],[118.818758,31.877683],[118.823644,31.863646],[118.828675,31.833341],[118.830615,31.829829],[118.847719,31.829997],[118.849551,31.825948],[118.857313,31.826837],[118.864571,31.825733],[118.87193,31.824661],[118.880123,31.824293],[118.891765,31.826471],[118.895789,31.826348],[118.897945,31.823526],[118.905527,31.814076],[118.905725,31.809442],[118.90691,31.804931],[118.908204,31.802292],[118.909069,31.796939],[118.913385,31.794848],[118.918371,31.792438],[118.923231,31.788533],[118.928117,31.784643],[118.934837,31.782095],[118.935852,31.783806],[118.954626,31.775902],[118.95954,31.773492],[118.967571,31.775196],[118.976841,31.775772],[118.979402,31.774789],[118.980201,31.773346],[118.983902,31.77231],[118.985034,31.776447],[118.985048,31.781869],[118.998464,31.784773],[119.011794,31.787674],[119.01519,31.79497],[119.012522,31.79939],[119.01272,31.804469],[119.009118,31.80654],[119.006674,31.807215],[119.004985,31.807077],[119.00238,31.810414],[118.998661,31.815078],[118.998203,31.818239],[118.996119,31.818369],[118.993846,31.822028],[118.988636,31.825395],[118.98498,31.828026],[118.978072,31.829775],[118.978243,31.836769],[118.978404,31.843978],[118.985645,31.843932],[118.98692,31.850741],[119.035519,31.854836],[119.041088,31.860448],[119.052245,31.861169],[119.054132,31.864742],[119.07594,31.875596],[119.079461,31.870874],[119.099925,31.865998],[119.101775,31.867409],[119.103608,31.869831],[119.107237,31.871533],[119.108135,31.87552],[119.109339,31.877865],[119.109626,31.882802],[119.111818,31.886205],[119.11401,31.890819],[119.11622,31.89223],[119.119975,31.893303],[119.122131,31.894897],[119.123532,31.89784],[119.122634,31.915343],[119.122454,31.930268],[119.111136,31.936642],[119.08875,31.94225],[119.083252,31.942464],[119.074269,31.946202],[119.071933,31.946325],[119.068592,31.945375],[119.051272,31.943414],[119.031222,31.954566],[119.033522,31.96535],[119.051811,31.977756],[119.071538,31.979655],[119.082895,31.975107],[119.091445,31.97993],[119.098077,31.979365],[119.10573,31.974005],[119.113348,31.968705],[119.118502,31.974754],[119.121736,31.985841],[119.127218,31.986623],[119.127808,31.990588],[119.119903,31.993436],[119.112989,32.004569],[119.109339,32.003082],[119.09705,32.00694],[119.089487,32.008377],[119.075473,32.010811],[119.061837,32.010229],[119.044596,32.009112],[118.970719,32.027611],[118.998347,32.065674],[119.003411,32.086192],[119.029464,32.092903],[119.089148,32.105046],[119.08559,32.112723],[119.064247,32.107524],[119.059468,32.111072],[119.05088,32.107218],[119.046891,32.1152],[119.046096,32.118071],[119.015035,32.120373],[119.007689,32.115445],[119.004851,32.108472],[118.993244,32.100856],[118.995544,32.09584],[118.994356,32.086192],[118.984239,32.07992],[118.973154,32.08405],[118.976159,32.095985],[118.985373,32.102835],[118.993334,32.116569],[118.989993,32.12134],[118.981441,32.120147],[118.972098,32.106965],[118.958193,32.106262],[118.938322,32.084819],[118.926932,32.083014],[118.925081,32.070783],[118.935933,32.07317],[118.941322,32.074149],[118.950018,32.073231],[118.960582,32.071579],[118.969637,32.069192],[118.966475,32.05787],[118.95086,32.029573],[118.919814,31.996261],[118.87878,31.972005],[118.885248,31.963301],[118.889919,31.959227],[118.895093,31.956075],[118.928438,31.922492],[118.943242,31.906431],[118.948807,31.898541],[118.932135,31.894617],[118.91345,31.875975],[118.894662,31.88166],[118.86376,31.88399],[118.859592,31.904346],[118.849531,31.891593],[118.833146,31.882518],[118.815467,31.879697],[118.810724,31.886811],[118.805478,31.896683],[118.803107,31.909986],[118.792902,31.910412],[118.785715,31.90704],[118.778493,31.902538],[118.772025,31.901802],[118.768576,31.907994],[118.767354,31.913327],[118.762914,31.918463],[118.761693,31.920792],[118.753644,31.920363],[118.75271,31.923332],[118.751416,31.920451],[118.741714,31.923857],[118.740133,31.921528],[118.733234,31.923979],[118.729641,31.937034],[118.725042,31.938995],[118.722095,31.933541],[118.6986,31.930852],[118.685593,31.924163],[118.682961,31.919918],[118.687147,31.914417],[118.694082,31.913344],[118.697585,31.907896],[118.686576,31.90311],[118.680989,31.908244],[118.674036,31.907677],[118.67285,31.904941],[118.672374,31.903715],[118.671808,31.902504],[118.636056,31.897055],[118.613275,31.907233],[118.603645,31.911892],[118.603861,31.916489],[118.61385,31.932855],[118.616581,31.934326],[118.607813,31.9407],[118.595335,31.933812]]]}},{"type":"Feature","properties":{"id":1100005726,"name":"梅山","longitude":118.641877,"latitude":31.907922,"unit_price":16319,"count":"23.21℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.636559,31.898283],[118.671521,31.902757],[118.65298,31.910452],[118.654309,31.912613],[118.650411,31.914452],[118.648866,31.915682],[118.633289,31.922517],[118.63151,31.923743],[118.619383,31.928585],[118.615646,31.930129],[118.60519,31.916735],[118.605046,31.911953],[118.636559,31.898283]]]}},{"type":"Feature","properties":{"id":611100505,"name":"顶山街道","longitude":118.68733720812,"latitude":32.101801191274,"unit_price":23655,"count":"23.38℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.66548904832,32.094212172336],[118.68144063391,32.086193893083],[118.68429213054,32.059498963255],[118.692256,32.046343],[118.719101,32.083309],[118.724904,32.091217],[118.730653,32.099109],[118.71650033092,32.106481624047],[118.68349698863,32.123721150003],[118.66166886938,32.126152706416],[118.65256503122,32.121043525874],[118.63586315749,32.107994247136],[118.66548904832,32.094212172336]]]}},{"type":"Feature","properties":{"id":611100541,"name":"泰山街道","longitude":118.71845310611,"latitude":32.153434378151,"unit_price":19891,"count":"24.59℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.71953358435,32.161044257865],[118.71308437206,32.162419943283],[118.70256657283,32.16352381618],[118.69412884759,32.165249066368],[118.69091539704,32.165191340583],[118.70266503182,32.151077357029],[118.7043997336,32.152067513042],[118.70804650769,32.146647043403],[118.71350023754,32.143839477283],[118.7209009783,32.142990409659],[118.72782217409,32.14977532226],[118.73094623268,32.157840015406],[118.73497038339,32.169290711551],[118.72387876897,32.17625857129],[118.71953358435,32.161044257865],[118.71953358435,32.161044257865]]]}},{"type":"Feature","properties":{"id":613000138,"name":"高新区","longitude":118.70717492306,"latitude":32.171118352741,"unit_price":22585,"count":"32.47℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.690658,32.184182],[118.6879552693,32.171034151777],[118.69089783475,32.165281774024],[118.69404874198,32.165325625576],[118.7023548349,32.163628225274],[118.71310839188,32.162449352575],[118.71944776479,32.161103084518],[118.730327,32.197963],[118.690478,32.18843],[118.690658,32.184182]]]}},{"type":"Feature","properties":{"id":613000148,"name":"桥北","longitude":118.73572895635,"latitude":32.136696978587,"unit_price":22518,"count":"23.22℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.73129104666,32.158562570224],[118.72785538722,32.149744965075],[118.72094321863,32.142954920801],[118.71351684648,32.14378681218],[118.70805245656,32.146558768268],[118.7043711033,32.152026158299],[118.70262742108,32.151029857552],[118.69582445833,32.145369792284],[118.69426822259,32.14238435284],[118.69075232729,32.135775704315],[118.68551678725,32.130291947745],[118.68364085859,32.123827864546],[118.70510599226,32.112855331986],[118.71639843106,32.106688261681],[118.731633,32.102201],[118.746293,32.121286],[118.772739,32.14269],[118.779638,32.14966],[118.779351,32.159075],[118.73499889995,32.169241567092],[118.73129104666,32.158562570224]]]}},{"type":"Feature","properties":{"id":611100777,"name":"高淳","longitude":118.89315170665,"latitude":31.335421625319,"unit_price":8838,"count":"22.08℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[119.00655304445,31.238460324243],[119.02568455806,31.247925414342],[119.02934723094,31.244409666499],[119.04589006148,31.244549801131],[119.05528229858,31.23987972538],[119.07412343928,31.243443627093],[119.08302007729,31.238113433008],[119.0911071121,31.245896726793],[119.11186015156,31.240315434242],[119.11364410063,31.256277580718],[119.11858748314,31.262011615408],[119.13872446198,31.268813949115],[119.1471415368,31.28224608313],[119.15654700652,31.283496047412],[119.1639503727,31.298873401221],[119.1804890569,31.299141366825],[119.18742181446,31.306364426283],[119.19488598729,31.307364230535],[119.19538120192,31.313865635141],[119.20236550771,31.316169434844],[119.20025365681,31.324359151681],[119.20575466268,31.336522774821],[119.2256402317,31.355993486958],[119.2207908248,31.36159736617],[119.21110294542,31.363641519624],[119.20692604272,31.374645949989],[119.19630519876,31.38535575649],[119.18059465875,31.387216864404],[119.17563757274,31.400366115577],[119.17567534031,31.427835956259],[119.17086147726,31.447274719741],[119.16199548131,31.445006198203],[119.147153,31.451846],[119.144791,31.447657],[119.152026,31.425516],[119.13795,31.424491],[119.141197,31.44349],[119.13817,31.447884],[119.13287,31.443413],[119.128347,31.428466],[119.122212,31.426976],[119.118978,31.429267],[119.11088,31.42473],[119.106909,31.429175],[119.089082,31.431363],[119.089509,31.438526],[119.074777,31.431937],[119.068965,31.438368],[119.057511,31.429934],[119.050105,31.43573],[119.040794,31.43578],[119.024224,31.420189],[119.026556,31.407164],[119.016652,31.392004],[119.007866,31.389615],[119.001381,31.401312],[118.994311,31.399529],[118.986091,31.390343],[118.976533,31.386644],[118.966652,31.393025],[118.963095,31.401393],[118.953465,31.404799],[118.946422,31.411471],[118.946243,31.418344],[118.938769,31.426386],[118.932157,31.443332],[118.887188,31.493736],[118.87276230727,31.450980080079],[118.87596096079,31.428663181435],[118.85815264704,31.401972501635],[118.83553182196,31.383750014161],[118.81725549455,31.376275854821],[118.79216712099,31.37497732167],[118.7785081416,31.370372106251],[118.77590589753,31.371215702669],[118.77914150135,31.381005575333],[118.77315367924,31.393513875585],[118.76371603238,31.391752614279],[118.75137862165,31.374782767649],[118.74557933868,31.35774871779],[118.7277609526,31.331687376657],[118.71559716492,31.306280613608],[118.70772356446,31.303628909305],[118.69974568815,31.305008413086],[118.7258838281,31.285039542519],[118.76290407376,31.276072079423],[118.77514060832,31.264632365588],[118.78407553403,31.246914061866],[118.80221567326,31.235715086902],[118.82594473005,31.242093720168],[118.83143622231,31.235922349554],[118.83780953442,31.235348266634],[118.85818664806,31.245993272581],[118.87690148284,31.248183175399],[118.90432410669,31.244421494171],[118.92213108903,31.250627221227],[118.95288841917,31.241715670953],[118.98810420454,31.24417384648],[118.99308607049,31.236826760355],[119.00655304445,31.238460324243]]]}},{"type":"Feature","properties":{"id":61140067,"name":"将军大道","longitude":118.79557488619,"latitude":31.928796214443,"unit_price":28390,"count":"28.17℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.79697323505,31.910373021567],[118.80122820782,31.910335613817],[118.80300735936,31.909921369289],[118.80258651506,31.917816258251],[118.80186926469,31.933602499469],[118.80031895491,31.941396542198],[118.7980263454,31.949218966103],[118.79361424067,31.963200578199],[118.792105,31.967557],[118.785592,31.967978],[118.785246,31.968307],[118.775998,31.964532],[118.775549,31.960703],[118.7655973939,31.953358720022],[118.76037853785,31.948199172845],[118.75934227517,31.940763005674],[118.75934732824,31.936227092451],[118.75839021879,31.93097666512],[118.75944399282,31.927292651463],[118.7616981528,31.923764711093],[118.76374797772,31.917962183013],[118.76765405663,31.913164034429],[118.768226748,31.908969918488],[118.77211052806,31.901869234523],[118.77822996995,31.902437069425],[118.79208216689,31.910280749868],[118.79697323505,31.910373021567]]]}},{"type":"Feature","properties":{"id":61140069,"name":"江宁大学城","longitude":118.895422,"latitude":31.91365,"unit_price":24806,"count":"33.68℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.88616023757,31.9462301263],[118.872695,31.94379],[118.873683,31.936896],[118.87442,31.931487],[118.874851,31.928775],[118.874932,31.927963],[118.875048,31.927181],[118.875291,31.925526],[118.873405,31.922967],[118.872443,31.921611],[118.871329,31.919903],[118.868985,31.916163],[118.866515,31.912531],[118.863397,31.908669],[118.86028,31.90483],[118.86499954419,31.884110159613],[118.914544,31.877115],[118.93164468894,31.89625760333],[118.94756246905,31.899321315155],[118.92320954921,31.926395452471],[118.89973675488,31.951896068419],[118.89221780207,31.948473340231],[118.88616023757,31.9462301263]]]}},{"type":"Feature","properties":{"id":61140078,"name":"百家湖","longitude":118.81558415722,"latitude":31.942444813065,"unit_price":29023,"count":"20.82℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.80236204317,31.927413978882],[118.80264897601,31.917960294352],[118.81357243982,31.924258868203],[118.82089794394,31.925195029935],[118.83028311392,31.92785061514],[118.84356928476,31.933069573435],[118.8424442779,31.93587185798],[118.830826434,31.961628903117],[118.81401326322,31.961304147306],[118.79371184016,31.96326545356],[118.79803109573,31.949638151174],[118.80045612333,31.941187610002],[118.80190621154,31.93370739682],[118.80236204317,31.927413978882],[118.80236204317,31.927413978882]]]}},{"type":"Feature","properties":{"id":613000143,"name":"九龙湖","longitude":118.82994046666,"latitude":31.90530403191,"unit_price":30067,"count":"28.62℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.8031048131,31.909741804241],[118.80576304845,31.896549320469],[118.81139029082,31.885922905023],[118.81622017622,31.879927051349],[118.82151877331,31.880313551682],[118.83732667699,31.884161832734],[118.84775730566,31.889644820642],[118.85858332625,31.903441758128],[118.85853905192,31.916366585241],[118.84535149896,31.928557770256],[118.84362399396,31.932993735499],[118.83039482068,31.927806858978],[118.82096785057,31.925144750229],[118.81359386667,31.92421612106],[118.80264701272,31.917887569925],[118.8031048131,31.909741804241],[118.8031048131,31.909741804241]]]}},{"type":"Feature","properties":{"id":1100000572,"name":"科学园","longitude":118.862179,"latitude":31.929077,"unit_price":26499,"count":"26.52℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.872581,31.943632],[118.875106,31.925629],[118.872509,31.922036],[118.870039,31.918312],[118.868054,31.915071],[118.866149,31.912466],[118.859969,31.904848],[118.85731,31.910182],[118.859251,31.915576],[118.855622,31.921338],[118.850914,31.925077],[118.846064,31.927407],[118.843045,31.935834],[118.852352,31.937979],[118.864623,31.941671],[118.870273,31.943402],[118.870273,31.943402],[118.872581,31.943632]]]}},{"type":"Feature","properties":{"id":1100005808,"name":"正方新城","longitude":118.793151,"latitude":31.851213,"unit_price":19364,"count":"28.31℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.818434,31.87756],[118.789958,31.883041],[118.782879,31.884145],[118.767536,31.883838],[118.757655,31.885126],[118.763512,31.880987],[118.76635,31.880051],[118.761859,31.856975],[118.756649,31.846332],[118.75575,31.827006],[118.756487,31.826699],[118.777885,31.824839],[118.796066,31.827497],[118.81008,31.831516],[118.811338,31.834185],[118.815146,31.829338],[118.817877,31.82946],[118.821902,31.830135],[118.82571,31.828509],[118.830561,31.829583],[118.828801,31.83305],[118.823501,31.863454],[118.818434,31.87756]]]}},{"type":"Feature","properties":{"id":611100931,"name":"六合其它","longitude":118.807596,"latitude":32.348416,"unit_price":10044,"count":"20.43℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.751758,32.313652],[118.760606,32.314705],[118.766858,32.301445],[118.778923,32.297416],[118.791167,32.29354],[118.798012,32.287359],[118.811163,32.278766],[118.812061,32.276873],[118.815708,32.268417],[118.821565,32.27121],[118.826704,32.271348],[118.831608,32.27121],[118.831986,32.26776],[118.832183,32.264494],[118.833028,32.256311],[118.837825,32.252982],[118.844005,32.248814],[118.853275,32.242416],[118.859851,32.237835],[118.857875,32.235178],[118.854767,32.231009],[118.863396,32.220449],[118.874198,32.201164],[118.882193,32.183331],[118.919478,32.182632],[118.95293,32.181165],[118.967519,32.18037],[119.008985,32.180401],[119.027346,32.185649],[119.047567,32.199159],[119.062569,32.211537],[119.071516,32.223939],[119.083993,32.238844],[119.094432,32.244074],[119.08643861322,32.252579845498],[119.08075261735,32.252253374035],[119.06795042356,32.248695699699],[119.06567918898,32.248542573572],[119.06078762386,32.254421134502],[119.04453597916,32.260930981834],[119.05043443393,32.276473815165],[119.04252464269,32.301235118444],[119.04601167754,32.309817916154],[119.04193228998,32.315411206071],[119.04423042153,32.330874903038],[119.05075242164,32.339345436753],[119.03294587497,32.351882564002],[119.03236736186,32.356806409283],[119.04155611006,32.36228557093],[119.05212449157,32.374847743513],[119.02886495735,32.383723589431],[119.03138080367,32.387742657204],[119.0451313479,32.387647016745],[119.04631656853,32.389865768281],[119.04581031821,32.393470915704],[119.03166614384,32.396428637696],[119.02645655792,32.417259338594],[119.02761412094,32.428714965022],[119.02308926885,32.450323094213],[119.02894323873,32.45902278444],[119.03396773595,32.456096752929],[119.04893404753,32.474437210426],[119.07305443363,32.47227834071],[119.0735952696,32.477153463853],[119.07489799363,32.480151422226],[119.07490169434,32.487062562822],[119.06952475389,32.491630419035],[119.06291697688,32.496846281117],[119.05831513219,32.501976056385],[119.05272477865,32.513239210075],[119.04956187861,32.517715761414],[119.04361261568,32.520828000054],[119.03906334062,32.519424620659],[119.03541639948,32.52001635426],[119.03208893736,32.519695790009],[119.02649828191,32.521377714506],[119.02005957709,32.520647095317],[119.01072534223,32.515095447788],[119.00644866602,32.511153346214],[119.00279779013,32.508937074199],[118.99535839661,32.509003470274],[118.98936952776,32.510207379042],[118.9880853035,32.512094174239],[118.985443534,32.512758735991],[118.97998187563,32.519172373512],[118.97720775542,32.530273686764],[118.97575732918,32.53337655221],[118.9674982454,32.53925709025],[118.95951991221,32.547674732845],[118.95239686433,32.554643863943],[118.94641094998,32.56117496356],[118.94069220824,32.563102943913],[118.93302683004,32.561769085792],[118.92546492709,32.55799324373],[118.92214185771,32.556279583874],[118.91709816818,32.554850771539],[118.90998543751,32.55756602258],[118.90609660667,32.558056838751],[118.90122121247,32.560209011407],[118.89944873412,32.562954267826],[118.90643430257,32.567336463892],[118.9083488825,32.571407588743],[118.90849867309,32.577488217941],[118.915637,32.587479],[118.916697,32.590415],[118.91623,32.592392],[118.914218,32.594704],[118.906097,32.594681],[118.906075,32.594567],[118.894491,32.591],[118.887413,32.579409],[118.884233,32.577538],[118.855056,32.572563],[118.85051,32.572503],[118.843683,32.57445],[118.829966,32.586285],[118.828367,32.589753],[118.830968,32.593381],[118.835648,32.596023],[118.836595,32.601217],[118.833932,32.607312],[118.831457,32.609532],[118.825465,32.608148],[118.820996,32.605358],[118.818733,32.602191],[118.817969,32.598936],[118.812575,32.590886],[118.799316,32.587449],[118.793903,32.588726],[118.788258,32.591369],[118.784925,32.595369],[118.784175,32.604651],[118.781673,32.606521],[118.769011,32.606552],[118.75326,32.599449],[118.746868,32.594616],[118.740962,32.597761],[118.739439,32.60081],[118.738177,32.605419],[118.733888,32.6126],[118.711628,32.612475],[118.708573,32.603913],[118.704589,32.596099],[118.696347,32.59502],[118.690095,32.597541],[118.679262,32.597529],[118.671271,32.600423],[118.662203,32.601191],[118.648751,32.585524],[118.641488,32.585688],[118.635375,32.59024],[118.62296,32.59678],[118.616493,32.599761],[118.610137,32.602689],[118.60194,32.603202],[118.591884,32.597244],[118.57919,32.596609],[118.546811,32.59073],[118.535412,32.572476],[118.547197,32.553335],[118.577704,32.538688],[118.599209,32.509698],[118.600629,32.486923],[118.627614,32.478056],[118.65547,32.480326],[118.698193,32.474953],[118.698665,32.471264],[118.697354,32.466154],[118.697731,32.461595],[118.697619,32.458446],[118.696244,32.456622],[118.694578,32.444004],[118.693203,32.435986],[118.69544,32.42639],[118.692184,32.412156],[118.691223,32.409824],[118.684719,32.400245],[118.686048,32.395938],[118.693994,32.391426],[118.706103,32.367771],[118.847014,32.373609],[118.866705,32.367693],[118.862896,32.36019],[118.865987,32.357018],[118.868071,32.353602],[118.853554,32.329991],[118.85801,32.320471],[118.851542,32.311195],[118.829264,32.309852],[118.809968,32.324316],[118.791463,32.324224],[118.791679,32.330998],[118.8035,32.334079],[118.809717,32.32697],[118.813705,32.329106],[118.808279,32.340669],[118.82912,32.352321],[118.838606,32.365192],[118.838175,32.370651],[118.84626,32.373487],[118.705945,32.367327],[118.703125,32.349246],[118.705995,32.348282],[118.707446,32.347778],[118.708776,32.347302],[118.714206,32.34533],[118.715055,32.342779],[118.711758,32.336358],[118.706462,32.334726],[118.6992,32.336133],[118.694111,32.33624],[118.69032,32.333372],[118.690266,32.330763],[118.694007,32.328845],[118.698903,32.328727],[118.701948,32.327575],[118.703574,32.324962],[118.701225,32.323124],[118.691991,32.324322],[118.682527,32.321507],[118.678363,32.317079],[118.666587,32.311258],[118.664152,32.308157],[118.664211,32.304777],[118.666515,32.302438],[118.672488,32.301961],[118.67336,32.302751],[118.675907,32.299455],[118.675438,32.294704],[118.689056,32.299145],[118.705333,32.304253],[118.722446,32.309792],[118.727971,32.310482],[118.736235,32.311577],[118.742694,32.312447],[118.751758,32.313652]]]}},{"type":"Feature","properties":{"id":1100004265,"name":"南门新城","longitude":118.84378,"latitude":32.325963,"unit_price":15142,"count":"21.68℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.847194,32.344665],[118.85456,32.342163],[118.857686,32.340791],[118.859051,32.338075],[118.859051,32.338075],[118.85562,32.334342],[118.851649,32.330021],[118.851649,32.330021],[118.851649,32.330021],[118.85341,32.325627],[118.85341,32.325627],[118.85341,32.325627],[118.857219,32.321081],[118.857219,32.321081],[118.857219,32.321081],[118.850141,32.311866],[118.835157,32.309913],[118.833684,32.310478],[118.832246,32.309806],[118.829515,32.311988],[118.832929,32.31433],[118.832668,32.321776],[118.831698,32.327558],[118.831644,32.329419],[118.831375,32.331295],[118.830387,32.338663],[118.829336,32.346434],[118.828509,32.350979],[118.829713,32.350685],[118.830171,32.350666],[118.8308,32.350544],[118.831123,32.350621],[118.832049,32.350491],[118.833504,32.350506],[118.836558,32.350064],[118.839037,32.349332],[118.843924,32.346373],[118.847194,32.344665]]]}},{"type":"Feature","properties":{"id":1100004266,"name":"龙池","longitude":118.82638,"latitude":32.326665,"unit_price":13724,"count":"26.01℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.831339,32.328992],[118.831339,32.329968],[118.828303,32.350773],[118.808782,32.340729],[118.813957,32.328984],[118.809789,32.326574],[118.803447,32.333804],[118.791912,32.33083],[118.791885,32.324567],[118.810148,32.324682],[118.818897,32.317953],[118.827916,32.310935],[118.832704,32.314459],[118.831339,32.328992]]]}},{"type":"Feature","properties":{"id":1100004868,"name":"大厂","longitude":118.761029,"latitude":32.253436,"unit_price":16483,"count":"23.66℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.858046,32.237556],[118.832893,32.256245],[118.832893,32.256245],[118.831456,32.271145],[118.831456,32.271145],[118.821671,32.271107],[118.815646,32.268214],[118.815646,32.268214],[118.811179,32.278556],[118.798111,32.287019],[118.798111,32.287019],[118.791057,32.293452],[118.766203,32.301425],[118.766623,32.301632],[118.760454,32.314609],[118.760454,32.314609],[118.722509,32.309726],[118.722509,32.309726],[118.67842,32.29505],[118.669221,32.279665],[118.666347,32.2724],[118.667928,32.266843],[118.674827,32.263515],[118.681402,32.262966],[118.682804,32.260523],[118.682408,32.257897],[118.710939,32.255363],[118.727252,32.256378],[118.729417,32.222486],[118.735858,32.215918],[118.733526,32.207998],[118.739716,32.207089],[118.743879,32.201181],[118.741256,32.195452],[118.743412,32.185735],[118.739999,32.180478],[118.737232,32.18005],[118.741544,32.175222],[118.753905,32.190379],[118.773416,32.197132],[118.770731,32.209942],[118.772384,32.214158],[118.801057,32.234196],[118.808819,32.238106],[118.829875,32.240732],[118.836271,32.24006],[118.8528,32.23273],[118.858046,32.237556]]]}},{"type":"Feature","properties":{"id":61140001,"name":"龙江","longitude":118.752784,"latitude":32.060119,"unit_price":50005,"count":"20.12℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.736192,32.059216],[118.73499225669,32.052495014831],[118.75067542045,32.051910033807],[118.76239337948,32.051698525132],[118.76557988047,32.054217227089],[118.76392148473,32.055794400538],[118.76270149651,32.061683523426],[118.76226976076,32.066019833605],[118.76241064873,32.070371706319],[118.76377734317,32.074048302239],[118.76399574038,32.075681316414],[118.76385899486,32.076883716394],[118.76124808247,32.076605775637],[118.76001854048,32.076156862402],[118.75840326339,32.075231209098],[118.75646702172,32.07448719792],[118.75443136321,32.073913830811],[118.75300534131,32.072758545208],[118.75223961061,32.072428041295],[118.75069920789,32.07141082829],[118.74814322146,32.071013746322],[118.745516,32.070699],[118.746001,32.068618],[118.746513,32.066017],[118.746567,32.064403],[118.74663,32.063623],[118.744842,32.063539],[118.7431,32.063424],[118.743091,32.062146],[118.743091,32.060861],[118.743046,32.059415],[118.7416,32.059323],[118.740135,32.059262],[118.738159,32.059224],[118.736192,32.059216]]]}},{"type":"Feature","properties":{"id":61140012,"name":"丹凤街","longitude":118.79364448832,"latitude":32.060176867575,"unit_price":39969,"count":"25.08℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.790586,32.056612],[118.79594021017,32.056040678592],[118.79713957982,32.060870782147],[118.79720275097,32.064314313788],[118.79064,32.064641],[118.790604,32.060632],[118.790613,32.05862],[118.790608,32.057614],[118.790586,32.056612]]]}},{"type":"Feature","properties":{"id":61140016,"name":"水佐岗","longitude":118.76768151608,"latitude":32.0717215263,"unit_price":49295,"count":"29.31℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.76391330063,32.076932259246],[118.76410840751,32.075721508574],[118.76384272268,32.073968694602],[118.76251820661,32.070356645783],[118.76234789413,32.066074895494],[118.76566069501,32.066741660562],[118.77074195029,32.06632845985],[118.77080468535,32.068419927562],[118.77137473618,32.069673238343],[118.77160398211,32.071911152431],[118.77244195961,32.072358302222],[118.77339276681,32.073143254717],[118.77340392513,32.073849321843],[118.77368606921,32.074776333641],[118.77329253034,32.077107102999],[118.77249261516,32.079981006264],[118.77057870862,32.078169642668],[118.76821957144,32.077151439522],[118.76391330063,32.076932259246],[118.76391330063,32.076932259246]]]}},{"type":"Feature","properties":{"id":61140017,"name":"三牌楼","longitude":118.77126911893,"latitude":32.084469016082,"unit_price":35666,"count":"20.46℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.7607954196,32.079765551652],[118.76114698465,32.079077539917],[118.76191880552,32.078424503443],[118.76336961393,32.077460069747],[118.76391329919,32.076956401645],[118.76823037054,32.077181733073],[118.77057897553,32.078195145788],[118.77275681748,32.080252496842],[118.77567495537,32.082706755462],[118.77712280822,32.083193924572],[118.77908495804,32.083406337026],[118.7790548501,32.089400817631],[118.77903836826,32.092109993268],[118.77942173442,32.09373110319],[118.77743580489,32.094937573789],[118.77631758394,32.094623435004],[118.76610810039,32.085849396558],[118.76467753293,32.084629836772],[118.76283927103,32.083587648286],[118.76052642513,32.081815795214],[118.7607954196,32.079765551652],[118.7607954196,32.079765551652]]]}},{"type":"Feature","properties":{"id":61140018,"name":"马群","longitude":118.90659304729,"latitude":32.054896172194,"unit_price":26829,"count":"20.28℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.88430446634,32.051286556706],[118.88520822682,32.047852503022],[118.88689135321,32.046116800613],[118.88964603321,32.041978031713],[118.892389,32.041744],[118.898093,32.033686],[118.90316,32.039426],[118.90824,32.043515],[118.922105,32.051496],[118.92489,32.070797],[118.925339,32.073972],[118.925779,32.077031],[118.926651,32.083166],[118.924699,32.085396],[118.920387,32.088639],[118.918049,32.090013],[118.9146,32.092552],[118.903373,32.086297],[118.900691,32.084645],[118.897915,32.083207],[118.89236947402,32.080222795313],[118.88577032853,32.089330994404],[118.88289073881,32.096628141027],[118.8624564965,32.093432432712],[118.88430446634,32.051286556706]]]}},{"type":"Feature","properties":{"id":61140022,"name":"迈皋桥","longitude":118.83786078663,"latitude":32.112218074896,"unit_price":26148,"count":"32.01℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.81239959121,32.113489038925],[118.81067182736,32.111162589604],[118.810382,32.111201],[118.810575,32.108303],[118.810889,32.10765],[118.810871,32.107252],[118.810683,32.107],[118.810714,32.106346],[118.810741,32.105711],[118.812704,32.104514],[118.813186,32.104651],[118.815574,32.104262],[118.815628,32.104495],[118.822154,32.105447],[118.825389,32.105309],[118.832071,32.105088],[118.832507,32.107156],[118.840668,32.109259],[118.840497,32.108781],[118.84034,32.108322],[118.843149,32.107339],[118.845195,32.105918],[118.84872671207,32.107043766017],[118.85181753218,32.1086469072],[118.85755866308,32.109873533377],[118.8713376515,32.109875775094],[118.8724136761,32.112081225388],[118.87122192488,32.115402838783],[118.86806844844,32.117407969578],[118.86206752573,32.124915406245],[118.85154378331,32.119367678837],[118.84528876044,32.117334470631],[118.84285151249,32.117726637255],[118.84214172503,32.1184329222],[118.8408700763,32.118482316656],[118.84074160269,32.117576110807],[118.83906511515,32.117832661706],[118.83880971312,32.11617029379],[118.83255150805,32.115998977587],[118.82200813118,32.119848086808],[118.81992897844,32.117513915772],[118.81809942628,32.115258579165],[118.81239959121,32.113489038925]]]}},{"type":"Feature","properties":{"id":61140025,"name":"珠江路","longitude":118.80351993529,"latitude":32.058306307157,"unit_price":53394,"count":"31.85℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.79721208663,32.060840754845],[118.79598565283,32.056028911731],[118.81085117358,32.053218242085],[118.81208421239,32.051650137808],[118.81353542783,32.056007075705],[118.81416977939,32.058918586574],[118.80862650273,32.059515701552],[118.80576263494,32.060517150372],[118.80621694705,32.062421189264],[118.80429558504,32.062795860903],[118.80433126702,32.063050427691],[118.80130935452,32.06413107103],[118.79726173759,32.064295019377],[118.79721208663,32.060840754845],[118.79721208663,32.060840754845]]]}},{"type":"Feature","properties":{"id":61140028,"name":"热河南路","longitude":118.74494559014,"latitude":32.081865092049,"unit_price":35012,"count":"22.00℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.75340955823,32.092303079505],[118.74724663578,32.092664671918],[118.73917330208,32.093453734141],[118.737346,32.087617],[118.736843,32.084404],[118.73724109447,32.081404172233],[118.737274,32.081406],[118.739466,32.080672],[118.741622,32.080029],[118.745287,32.077704],[118.747766,32.076174],[118.750641,32.074736],[118.7522756467,32.072489275216],[118.75298584517,32.072776601381],[118.75436720081,32.073907929722],[118.75230786947,32.074969987671],[118.75135647975,32.076294133662],[118.75213805111,32.080238567352],[118.75236612804,32.084236029387],[118.75348804543,32.086149329843],[118.75315904521,32.090113857222],[118.75340955823,32.092303079505]]]}},{"type":"Feature","properties":{"id":61140029,"name":"五塘广场","longitude":118.79663080324,"latitude":32.115281580439,"unit_price":27749,"count":"25.59℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.78109458836,32.118561467835],[118.78263797641,32.118179444775],[118.78408036718,32.116778438597],[118.78038011177,32.114736296808],[118.77639568998,32.109889205201],[118.77974029928,32.108661800847],[118.78835911021,32.109474209763],[118.79454080613,32.109202526786],[118.80105974016,32.108967941899],[118.80144297327,32.108794117262],[118.80267891845,32.10950904253],[118.80332800868,32.108716047017],[118.80702900483,32.110965691831],[118.80861301655,32.111485550321],[118.81063536864,32.111232436564],[118.81239244977,32.113571252667],[118.81799358943,32.11527001139],[118.81804006735,32.116232004984],[118.81601938027,32.122220859383],[118.80531784294,32.120599254065],[118.80162240538,32.125776660172],[118.79276981853,32.124257922732],[118.7873011915,32.121115339487],[118.78240996692,32.121582120427],[118.77857131996,32.119254790526],[118.78109458836,32.118561467835],[118.78109458836,32.118561467835]]]}},{"type":"Feature","properties":{"id":61140030,"name":"小市","longitude":118.79074311771,"latitude":32.103673101853,"unit_price":27542,"count":"28.88℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.7779023099,32.104784724433],[118.78112202476,32.102019730954],[118.78672558274,32.099515164377],[118.790703,32.098569],[118.793231,32.097613],[118.79567,32.09663],[118.798051,32.095678],[118.800337,32.094749],[118.802057,32.098592],[118.802354,32.099968],[118.802502,32.100668],[118.802646,32.101379],[118.806279,32.102568],[118.810618,32.105719],[118.810218,32.111247],[118.80866001989,32.111437988828],[118.80709688565,32.110912764962],[118.80332861793,32.108649334966],[118.80267027134,32.109484061217],[118.80145084621,32.108777883332],[118.80104132844,32.108959168399],[118.793174573,32.109201537549],[118.78847532897,32.109425801295],[118.7797225262,32.108619978969],[118.77635062967,32.109875342708],[118.77420430206,32.107198063377],[118.7779023099,32.104784724433]]]}},{"type":"Feature","properties":{"id":61140040,"name":"万寿","longitude":118.84945897608,"latitude":32.130433545634,"unit_price":25707,"count":"21.74℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.84119059981,32.143314457539],[118.8416649718,32.133586598214],[118.83426605913,32.133029702991],[118.83498560057,32.128015732645],[118.83492350034,32.123651481644],[118.83353000578,32.119501038298],[118.83380841295,32.116116465212],[118.83875483314,32.116265954411],[118.83902880506,32.11789570685],[118.84068674521,32.117654940386],[118.84077953554,32.118530603008],[118.84215066871,32.118497038765],[118.84287654534,32.117778268599],[118.84530560165,32.117398465044],[118.85143868407,32.119389135517],[118.86200502719,32.124977249524],[118.863583183,32.133015675553],[118.8583080502,32.144016829521],[118.85365755554,32.156579088135],[118.84769639156,32.150276572815],[118.84406695455,32.147668695339],[118.84040617323,32.146037343536],[118.83820343431,32.145616029889],[118.84119059981,32.143314457539]]]}},{"type":"Feature","properties":{"id":61140041,"name":"月苑","longitude":118.86814302653,"latitude":32.101849492761,"unit_price":27764,"count":"24.90℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.838898,32.095757],[118.84526664235,32.096343980711],[118.88186855226,32.10043283548],[118.89232930706,32.103278163598],[118.89597215461,32.105378541127],[118.899332,32.10898],[118.89566657488,32.111091043955],[118.88942520864,32.110633069436],[118.88585776766,32.110146234168],[118.88297592334,32.111177286729],[118.88135767066,32.112721092923],[118.88048091203,32.114241900304],[118.87126564998,32.109807647474],[118.8574554377,32.109778953359],[118.85182221812,32.108588540395],[118.84874959903,32.10703528844],[118.84507673101,32.105888772575],[118.84335538746,32.107068851443],[118.84308,32.107275],[118.842366,32.107531],[118.841549,32.107802],[118.841073,32.107986],[118.840215,32.10828],[118.84034,32.108689],[118.840426,32.109026],[118.840219,32.108984],[118.83955,32.108796],[118.838575,32.108544],[118.836626,32.108013],[118.832714,32.106996],[118.83257,32.106541],[118.832431,32.105998],[118.832188,32.104943],[118.831191,32.105033],[118.831065,32.101301],[118.832826,32.10056],[118.832197,32.099],[118.834676,32.09822],[118.838898,32.095757]]]}},{"type":"Feature","properties":{"id":61140045,"name":"湖南路","longitude":118.78104251339,"latitude":32.072824453674,"unit_price":35226,"count":"22.17℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.77330359693,32.077109748874],[118.77370739216,32.074770218499],[118.77342470808,32.073842381879],[118.7734103085,32.07312296209],[118.77245572359,32.072344990351],[118.7716112674,32.071895821403],[118.77138472118,32.069663652293],[118.77081439748,32.068403281245],[118.77079431511,32.066312847499],[118.77667420493,32.065225028648],[118.78440502124,32.064833463935],[118.78833010524,32.065331610972],[118.790529,32.065251],[118.79050352121,32.083820449251],[118.77909764766,32.083396808093],[118.77710851431,32.083164362529],[118.77567496386,32.082682343688],[118.77250800071,32.079983729553],[118.77330359693,32.077109748874]]]}},{"type":"Feature","properties":{"id":61140047,"name":"北京东路","longitude":118.81406839811,"latitude":32.062638073765,"unit_price":48353,"count":"26.02℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.80432216693,32.062814907775],[118.80623811612,32.062438014905],[118.80578841609,32.060537515742],[118.80866479008,32.059536510539],[118.81402142007,32.058975288723],[118.81645703997,32.058480290424],[118.81949584926,32.058227059959],[118.82377004442,32.057861383105],[118.8238420254,32.058292286578],[118.82592496852,32.057905311034],[118.82669738511,32.061499958698],[118.81989425596,32.064824103385],[118.81776933506,32.067193967257],[118.81536128028,32.068818648845],[118.81323768667,32.069075114515],[118.8110710341,32.068199889506],[118.80568941627,32.069169684187],[118.80432216693,32.062814907775],[118.80432216693,32.062814907775]]]}},{"type":"Feature","properties":{"id":61140050,"name":"樱驼花园","longitude":118.841913,"latitude":32.092699,"unit_price":29268,"count":"20.94℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.83289398039,32.0907022081],[118.83508208871,32.088076706966],[118.83581292025,32.086277960836],[118.83655126255,32.086168508013],[118.83666943191,32.084158119795],[118.83904023189,32.081833372922],[118.85077297849,32.09170272619],[118.87000625152,32.094839399346],[118.88303243319,32.096828130002],[118.883056,32.096951],[118.882957,32.097295],[118.88267,32.098129],[118.882562,32.098411],[118.882391,32.098771],[118.882283,32.099169],[118.882113,32.099796],[118.881969,32.100163],[118.881888,32.100377],[118.83888862284,32.095658861029],[118.8317959648,32.093238939551],[118.83289398039,32.0907022081]]]}},{"type":"Feature","properties":{"id":61140052,"name":"锁金村","longitude":118.82424658649,"latitude":32.080083686573,"unit_price":30246,"count":"21.37℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.813778,32.082757],[118.811443,32.082328],[118.809359,32.082818],[118.81648754744,32.072449365763],[118.82028063526,32.06857750553],[118.81999493465,32.064790329826],[118.82753347417,32.070270910968],[118.83900916367,32.081798683407],[118.83659146103,32.084153600703],[118.83649784623,32.08613044334],[118.83578350819,32.086215853256],[118.83500741577,32.088031439744],[118.83285282941,32.090684245011],[118.83174665205,32.093206198166],[118.820228,32.088646],[118.818288,32.086688],[118.817803,32.086168],[118.817138,32.085556],[118.815845,32.084607],[118.813778,32.082757]]]}},{"type":"Feature","properties":{"id":61140054,"name":"玄武门","longitude":118.79548537753,"latitude":32.069391530611,"unit_price":53407,"count":"32.33℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.790647,32.064681],[118.80131183363,32.064199453576],[118.80433969689,32.063089514139],[118.80564629813,32.069182674433],[118.80399618121,32.069514324965],[118.80344312755,32.069340323894],[118.80188289189,32.070730140422],[118.80083239515,32.072138932248],[118.79948209798,32.072345105433],[118.79673410296,32.072625902493],[118.79635972674,32.073326135395],[118.79546424602,32.073632586504],[118.7949593853,32.076031366661],[118.79312201026,32.08535383054],[118.79372573605,32.090230567307],[118.79910635823,32.091389279256],[118.79905539029,32.092925621603],[118.800184,32.094674],[118.796083,32.096329],[118.795189,32.096662],[118.794295,32.097029],[118.790778,32.098432],[118.790567,32.095851],[118.790572,32.094257],[118.790576,32.093458],[118.790585,32.092666],[118.790626,32.091037],[118.790608,32.08942],[118.790635,32.086651],[118.790643,32.085271],[118.790639,32.083882],[118.790697,32.076712],[118.790706,32.073117],[118.790674,32.069531],[118.790647,32.064681]]]}},{"type":"Feature","properties":{"id":61140058,"name":"福建路","longitude":118.76820296682,"latitude":32.091144368879,"unit_price":30940,"count":"32.78℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.76055735792,32.0904803868],[118.76607917899,32.085889619062],[118.7763181083,32.094641887135],[118.77743929778,32.094956352675],[118.77775618547,32.095878428148],[118.77473892723,32.096467933246],[118.76988885826,32.094958056363],[118.76220494417,32.092633709064],[118.7607357404,32.092727477163],[118.75859647975,32.0921356092],[118.75871868059,32.091842420952],[118.76055735792,32.0904803868],[118.76055735792,32.0904803868]]]}},{"type":"Feature","properties":{"id":61140059,"name":"许府巷","longitude":118.78463428804,"latitude":32.089178763164,"unit_price":38204,"count":"26.98℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.779098454,32.083405774043],[118.7905,32.08384],[118.79048870518,32.08715453228],[118.790482,32.089362],[118.790478,32.090739],[118.790451,32.092116],[118.790428,32.0935],[118.790419,32.094199],[118.79035246444,32.094881822034],[118.78618236181,32.094796319603],[118.78121741957,32.094919987598],[118.77779696234,32.095854511135],[118.77746630309,32.09493895859],[118.77945680994,32.093748568247],[118.77906429048,32.092096371768],[118.77908534369,32.089411419498],[118.779098454,32.083405774043]]]}},{"type":"Feature","properties":{"id":61140060,"name":"挹江门","longitude":118.75666757279,"latitude":32.082156706875,"unit_price":28411,"count":"29.34℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.75316013462,32.090104913884],[118.75349427264,32.086150998246],[118.75237263001,32.084233081853],[118.75214129713,32.08025757216],[118.75141689707,32.07629169996],[118.75232981093,32.075006187188],[118.75438831944,32.073928431407],[118.75652114381,32.074547921154],[118.75844410625,32.075278039489],[118.7599555405,32.07616234093],[118.76124753992,32.076648899586],[118.76390114219,32.076929638495],[118.76327044095,32.077495805507],[118.76189367172,32.078404634685],[118.76111698281,32.079053010764],[118.76076865624,32.079762500255],[118.76049262306,32.081838972283],[118.76280576321,32.083582294499],[118.76467211097,32.084671524667],[118.76606595968,32.085858487385],[118.76042349193,32.090534048372],[118.75870004276,32.091810753421],[118.7534260716,32.092309425122],[118.75316013462,32.090104913884],[118.75316013462,32.090104913884]]]}},{"type":"Feature","properties":{"id":61140100,"name":"尧化门","longitude":118.88345508953,"latitude":32.126873135355,"unit_price":23746,"count":"25.95℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.86365999639,32.133128297555],[118.86204269869,32.125127343636],[118.86807731795,32.117503989831],[118.87129284386,32.115478554434],[118.87253338169,32.11209356585],[118.87153391888,32.110031820076],[118.88300998818,32.116146214535],[118.90734332708,32.131453712556],[118.89890875515,32.14067416387],[118.88402308157,32.138434817565],[118.87367532457,32.137256556095],[118.86365999639,32.133128297555],[118.86365999639,32.133128297555]]]}},{"type":"Feature","properties":{"id":611100513,"name":"宁海路","longitude":118.77605444149,"latitude":32.060471433893,"unit_price":72319,"count":"20.83℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.76235192449,32.066027201865],[118.76397280331,32.055775352283],[118.76561554584,32.054228098651],[118.76921276498,32.054354317047],[118.77288731631,32.053392201087],[118.77464865774,32.053861712509],[118.77566885007,32.054413140253],[118.77626025081,32.05506890237],[118.77659368516,32.056108370402],[118.77779595196,32.05753717568],[118.78293941087,32.05652461037],[118.78562522771,32.056229980016],[118.790477,32.056608],[118.790486,32.057147],[118.790481,32.057683],[118.790486,32.058754],[118.790477,32.060896],[118.790468,32.061975],[118.790454,32.063053],[118.790436,32.065207],[118.7883627785,32.065303078737],[118.78441255601,32.064788013733],[118.77673192349,32.065151773468],[118.77073356316,32.06629087036],[118.76565958854,32.066685755457],[118.76235192449,32.066027201865]]]}},{"type":"Feature","properties":{"id":611100540,"name":"燕子矶","longitude":118.82744345513,"latitude":32.139895214155,"unit_price":27270,"count":"30.81℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.82266884469,32.132654028503],[118.82767497283,32.133014982917],[118.83419107285,32.133119786467],[118.8416044505,32.133645460158],[118.84112845503,32.143334297357],[118.83798181164,32.145675477941],[118.84043403193,32.146139391136],[118.84394652717,32.147725568617],[118.84756070726,32.150245852019],[118.85112364627,32.15401182183],[118.84825098362,32.15960244346],[118.83230428915,32.15293330282],[118.82525764282,32.151135121793],[118.82305881019,32.146182690121],[118.81665652913,32.14391428482],[118.81267005043,32.13362924428],[118.8168780101,32.133408323081],[118.82266884469,32.132654028503],[118.82266884469,32.132654028503]]]}},{"type":"Feature","properties":{"id":611100542,"name":"金陵小区","longitude":118.76953594541,"latitude":32.112838374035,"unit_price":27016,"count":"23.81℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.75885836689,32.114677206375],[118.76113878131,32.109031814997],[118.7625187857,32.105097085227],[118.76817680883,32.105623814364],[118.77284902185,32.106400053687],[118.77420181735,32.107253070423],[118.7803565938,32.114773562519],[118.78401096311,32.116791884286],[118.782592352,32.11817809105],[118.78101794658,32.118534306965],[118.77854057612,32.119221400546],[118.77657220875,32.121332602683],[118.77405432735,32.124625096247],[118.75542720802,32.116244723102],[118.75885836689,32.114677206375],[118.75885836689,32.114677206375]]]}},{"type":"Feature","properties":{"id":611100568,"name":"红山","longitude":118.8169638116,"latitude":32.097388520976,"unit_price":31600,"count":"31.21℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.806282,32.102422],[118.802775,32.101266],[118.802497,32.099859],[118.802146,32.098429],[118.801334,32.096567],[118.800489,32.094655],[118.79937,32.093341],[118.804256,32.088844],[118.809682,32.083613],[118.813132,32.083338],[118.814659,32.08369],[118.81624,32.085082],[118.817318,32.085938],[118.818144,32.086932],[118.819653,32.089104],[118.838863,32.095708],[118.834596,32.098201],[118.832134,32.099011],[118.832673,32.100525],[118.830948,32.101259],[118.831142,32.105062],[118.825102,32.105246],[118.823625,32.105315],[118.822147,32.105372],[118.819847,32.105028],[118.815711,32.104439],[118.81563,32.104198],[118.813169,32.10458],[118.812701,32.104393],[118.810698,32.105613],[118.806282,32.102422]]]}},{"type":"Feature","properties":{"id":613000128,"name":"晓庄","longitude":118.82225829276,"latitude":32.126289631377,"unit_price":26853,"count":"28.55℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.8053546796,32.120660315083],[118.81604353738,32.122286005198],[118.81809910232,32.11623164661],[118.81805884788,32.115306200762],[118.81980272564,32.117484247758],[118.82199310453,32.119916363598],[118.83261173736,32.116017137185],[118.83373539038,32.116071975207],[118.83347758486,32.119603431609],[118.83483077997,32.123695507856],[118.83487242599,32.128097028311],[118.83420744025,32.133056553445],[118.8275526321,32.132966292985],[118.82266912446,32.1326149642],[118.81698708715,32.13333591926],[118.81269478019,32.133600884587],[118.80768001352,32.131138426474],[118.80169230111,32.125785660018],[118.8053546796,32.120660315083]]]}},{"type":"Feature","properties":{"id":613000139,"name":"建宁路","longitude":118.76455465714,"latitude":32.09895553232,"unit_price":29999,"count":"23.61℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.74664196439,32.092753703352],[118.75343065221,32.092339017162],[118.75870490793,32.091814875559],[118.75857023002,32.092154576907],[118.76072788447,32.092747718879],[118.76221033771,32.092648970701],[118.77477100045,32.096519790124],[118.77777991635,32.095902467239],[118.7812273804,32.094952171396],[118.78619963356,32.094812061183],[118.7903,32.094918],[118.79030082439,32.098555937535],[118.78672889993,32.099435213194],[118.78111830513,32.101959456895],[118.7778769784,32.104745198119],[118.77415277639,32.107170255841],[118.77286367258,32.10632628619],[118.76821656896,32.105559130756],[118.76247180686,32.105051415075],[118.76117610492,32.108741303105],[118.75880815394,32.114576298362],[118.75539588614,32.116157947102],[118.74318617853,32.100868313625],[118.73918659587,32.09348293064],[118.74664196439,32.092753703352]]]}},{"type":"Feature","properties":{"id":613000151,"name":"栖霞其它","longitude":118.90838786959,"latitude":32.156306752261,"unit_price":16795,"count":"21.65℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[119.015446,32.1234],[119.016075,32.127779],[119.015437,32.129048],[119.016057,32.133215],[119.015805,32.137466],[119.033823,32.136745],[119.042518,32.148118],[119.041856,32.152813],[119.041611,32.159585],[119.051605,32.164293],[119.056604,32.166646],[119.059115,32.167823],[119.061621,32.168996],[119.072185,32.168503],[119.082722,32.167983],[119.083831,32.176281],[119.084375,32.180415],[119.084635,32.182508],[119.084936,32.184643],[119.088633,32.184349],[119.092285,32.184097],[119.101483,32.185847],[119.122921,32.192149],[119.125571,32.191985],[119.128643,32.193967],[119.130588,32.195919],[119.14184,32.199681],[119.144993,32.19894],[119.148096,32.198176],[119.153113,32.19551],[119.161189,32.192462],[119.169489,32.191935],[119.175041,32.192821],[119.176972,32.193173],[119.179236,32.19299],[119.181095,32.193776],[119.188282,32.195396],[119.191462,32.195762],[119.195352,32.19273],[119.199646,32.191049],[119.20544,32.191515],[119.216183,32.195335],[119.223055,32.196068],[119.226729,32.205501],[119.229478,32.207946],[119.248307,32.219814],[119.199116,32.240553],[119.167244,32.249562],[119.15244,32.250997],[119.137635,32.252463],[119.118448,32.250326],[119.100302,32.246722],[119.09502,32.243882],[119.08424,32.238415],[119.0823,32.235667],[119.078311,32.230963],[119.072239,32.223999],[119.071233,32.22293],[119.06976,32.220791],[119.069149,32.219845],[119.068502,32.219142],[119.067316,32.217584],[119.063148,32.211169],[119.04917,32.19962],[119.027467,32.185106],[119.008998,32.179727],[118.969598,32.179865],[118.966688,32.180033],[118.943314,32.181102],[118.91985,32.181882],[118.882032,32.183119],[118.874055,32.200888],[118.868593,32.210588],[118.863167,32.220379],[118.853861,32.230963],[118.829912,32.237209],[118.816365,32.234796],[118.802819,32.232414],[118.795561,32.227664],[118.788231,32.22293],[118.773597,32.213483],[118.774495,32.196862],[118.780685,32.180392],[118.78099,32.149536],[118.775079,32.139829],[118.790566,32.135915],[118.805909,32.132182],[118.81257603998,32.133630348115],[118.81648906866,32.144090040437],[118.82298316286,32.146294457207],[118.8251605642,32.151375387419],[118.83199194778,32.153016827529],[118.84836505669,32.159825111573],[118.85127713616,32.154263460233],[118.85364738141,32.156763986602],[118.85874168795,32.143539565927],[118.86365424115,32.133589724437],[118.87393069861,32.137723828114],[118.89901868784,32.140993069965],[118.90790084698,32.131552208477],[118.88081665332,32.114279216505],[118.88200807112,32.11236635482],[118.88347333099,32.111252771177],[118.88606096536,32.110343652808],[118.89564882854,32.111298993544],[118.89958750092,32.109223128713],[118.91152131502,32.123071695404],[118.94983014619,32.140801464701],[118.97611878649,32.143111119301],[118.99622894196,32.147409542027],[118.99780857712,32.142579509742],[119.00377920745,32.136761572823],[119.00531993965,32.126556036417],[118.99927562448,32.126063563625],[118.99082656258,32.124314513947],[118.98206994922,32.122630262758],[118.981249,32.120381],[118.990107,32.121673],[118.992029,32.119128],[118.99388,32.116566],[118.989828,32.109616],[118.985714,32.102704],[118.976488,32.095822],[118.973636,32.084201],[118.984129,32.080285],[118.994239,32.08627],[118.994679,32.091126],[118.995083,32.095929],[118.99282344123,32.100921918731],[119.00452088014,32.108482615788],[119.005962,32.112055],[119.007417,32.115687],[119.014745,32.120663],[119.015446,32.1234]]]}},{"type":"Feature","properties":{"id":1100000381,"name":"定淮门大街","longitude":118.741932,"latitude":32.074519,"unit_price":60005,"count":"18.67℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.735617,32.069929],[118.735653,32.06996],[118.742336,32.070266],[118.748193,32.071],[118.752074,32.072316],[118.750098,32.074886],[118.744887,32.077793],[118.740899,32.080332],[118.736336,32.080883],[118.736336,32.080883],[118.735617,32.069929]]]}},{"type":"Feature","properties":{"id":1100000585,"name":"草场门大街","longitude":118.740059,"latitude":32.064551,"unit_price":41188,"count":"31.37℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.735756,32.06986],[118.740602,32.07012],[118.74526,32.070549],[118.745902,32.067106],[118.746208,32.06371],[118.743032,32.063603],[118.742979,32.059456],[118.74164,32.059365],[118.740158,32.059311],[118.737975,32.059242],[118.73449,32.05928],[118.735693,32.066548],[118.735756,32.06986]]]}},{"type":"Feature","properties":{"id":61140007,"name":"南湖","longitude":118.76575662053,"latitude":32.032422228216,"unit_price":31229,"count":"29.24℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.76070905773,32.039112024684],[118.75992529093,32.037104533701],[118.75782908131,32.037703422539],[118.7570427636,32.035731339494],[118.75560973669,32.032902151756],[118.7649085407,32.028779878165],[118.7665570592,32.027936663641],[118.76802332478,32.025714030086],[118.77016800962,32.025264220958],[118.771838,32.025248],[118.773505,32.02524],[118.773496,32.025596],[118.773841,32.027019],[118.774326,32.028757],[118.77456,32.032499],[118.774448,32.03349],[118.774259,32.034366],[118.774502,32.035365],[118.774708,32.036356],[118.76070905773,32.039112024684]]]}},{"type":"Feature","properties":{"id":61140008,"name":"水西门","longitude":118.76229086577,"latitude":32.040789925295,"unit_price":38617,"count":"22.38℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.760177,32.04342],[118.75863187232,32.039705245688],[118.75783937847,32.037722794223],[118.75989799992,32.037124283692],[118.76068880447,32.039135646455],[118.774647,32.036333],[118.775051,32.038831],[118.772581,32.045714],[118.771723,32.046437],[118.770465,32.045676],[118.770358,32.045213],[118.767061,32.042167],[118.764739,32.043388],[118.763935,32.043116],[118.762057,32.043258],[118.760177,32.04342]]]}},{"type":"Feature","properties":{"id":61140009,"name":"湖西街","longitude":118.75179107834,"latitude":32.031504667383,"unit_price":38413,"count":"32.62℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.74838730109,32.026397802437],[118.75148176986,32.025075509505],[118.75450803675,32.029548477866],[118.75557452609,32.032868479633],[118.75700462886,32.035746705588],[118.75013465159,32.037230794463],[118.74754166818,32.02665494615],[118.74838730109,32.026397802437],[118.74838730109,32.026397802437]]]}},{"type":"Feature","properties":{"id":61140013,"name":"新街口","longitude":118.78984533789,"latitude":32.041651306818,"unit_price":43185,"count":"27.20℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.78164827406,32.045405889813],[118.78040232973,32.040041420052],[118.78030615262,32.039388455817],[118.78472842605,32.037552271768],[118.78572238901,32.036588113198],[118.78678723411,32.036519752228],[118.79023572429,32.03571738742],[118.79253988307,32.035244626071],[118.79705958193,32.034750994966],[118.80075905616,32.045947464143],[118.801119,32.047183],[118.799695,32.047317],[118.798406,32.047409],[118.795806,32.047597],[118.79059692939,32.047915105407],[118.7826126804,32.048202750766],[118.78164827406,32.045405889813]]]}},{"type":"Feature","properties":{"id":61140031,"name":"朝天宫","longitude":118.77807777502,"latitude":32.042455515227,"unit_price":31042,"count":"31.18℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.772993,32.045715],[118.774341,32.042364],[118.775401,32.038829],[118.775347,32.037589],[118.77508658285,32.036286381228],[118.77595605753,32.036124128091],[118.77721319071,32.035754000414],[118.77791147354,32.035185078124],[118.77827465567,32.036610359835],[118.78019594774,32.039308557439],[118.78123139365,32.043708997837],[118.78161292793,32.04542261665],[118.782603,32.048301],[118.773955,32.04873],[118.772625,32.048056],[118.771664,32.047567],[118.772347,32.046695],[118.772993,32.045715]]]}},{"type":"Feature","properties":{"id":61140033,"name":"大光路","longitude":118.81874659837,"latitude":32.031285282901,"unit_price":35491,"count":"19.25℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.80678984237,32.035155798272],[118.80688348787,32.034226730848],[118.80709640862,32.032775016933],[118.80779667556,32.032684218342],[118.8069988723,32.029495374302],[118.8102681514,32.029393829274],[118.81184384078,32.028761355981],[118.82214075479,32.027008335613],[118.83145579317,32.029130024414],[118.83214830884,32.034469157413],[118.82289816658,32.035365114946],[118.82282142506,32.034446381559],[118.81778622927,32.034818305845],[118.81637026581,32.035820459262],[118.81544071694,32.03599178465],[118.8140735834,32.035659328298],[118.81307543804,32.035734521464],[118.80846345235,32.036912015707],[118.8073374313,32.037120964254],[118.80678984237,32.035155798272],[118.80678984237,32.035155798272]]]}},{"type":"Feature","properties":{"id":61140036,"name":"瑞金路","longitude":118.82095533129,"latitude":32.040459349189,"unit_price":38825,"count":"18.84℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.8079114669,32.039032373521],[118.80737788775,32.037151586988],[118.8086157432,32.036938831239],[118.81305890807,32.035788079108],[118.8140306871,32.035715805433],[118.81536655425,32.036064585837],[118.81639206392,32.035869368099],[118.8178015178,32.034883808195],[118.82275123437,32.034523068878],[118.82284539943,32.035435862922],[118.82735126919,32.034919724683],[118.83219744177,32.034546954165],[118.83373,32.04456],[118.828991,32.044959],[118.824244,32.045294],[118.823408,32.045395],[118.822505,32.045464],[118.820749,32.045605],[118.81725,32.045888],[118.810252,32.046451],[118.8079114669,32.039032373521]]]}},{"type":"Feature","properties":{"id":61140043,"name":"安德门","longitude":118.76377767924,"latitude":31.997465052505,"unit_price":31554,"count":"22.39℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.7599413509,31.994119758393],[118.76053216376,31.994371097026],[118.76934909018,31.98695767145],[118.76818856631,31.991561649972],[118.76888808067,31.999038052639],[118.77030774274,32.000814981618],[118.77250064729,32.002313499972],[118.7704805356,32.002792815188],[118.76813002256,32.002573159227],[118.76537487387,32.003054103422],[118.760049,32.004699],[118.755593,31.998705],[118.756384,31.998169],[118.7599413509,31.994119758393]]]}},{"type":"Feature","properties":{"id":61140044,"name":"华侨路","longitude":118.77967877175,"latitude":32.051815704172,"unit_price":61231,"count":"23.44℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.76561985036,32.054209173277],[118.76994846038,32.050639906753],[118.772447,32.048216],[118.773144,32.048579],[118.773822,32.048893],[118.775457,32.048816],[118.777029,32.048715],[118.778506,32.048644],[118.779953,32.048572],[118.78267,32.048424],[118.790458,32.048055],[118.790494,32.05659],[118.78553879067,32.056206020833],[118.78282034251,32.056513005932],[118.77778731094,32.057532130186],[118.7765747731,32.056086309641],[118.77626700372,32.055074998211],[118.77564615563,32.05438802415],[118.77462165584,32.053849270147],[118.77287300437,32.053385697026],[118.76922112435,32.054342795138],[118.76561985036,32.054209173277]]]}},{"type":"Feature","properties":{"id":61140049,"name":"孝陵卫","longitude":118.87639869898,"latitude":32.038870749525,"unit_price":34745,"count":"32.58℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.84821923116,32.047026910383],[118.85493639266,32.045548125447],[118.85504337366,32.043189553187],[118.85697911612,32.042657234055],[118.85741669886,32.034625039531],[118.87027371299,32.034826666245],[118.87098121198,32.029509622702],[118.88376408859,32.031495685484],[118.882974,32.017856],[118.8846,32.01882],[118.886226,32.019761],[118.890772,32.024124],[118.892847,32.025364],[118.894985,32.02642],[118.895757,32.026994],[118.896108,32.027698],[118.896988,32.027935],[118.898124,32.027633],[118.900168,32.028421],[118.89803,32.033537],[118.892299,32.041664],[118.8895806054,32.04188598661],[118.88675735853,32.046077704491],[118.88512903497,32.047810031251],[118.88413509678,32.051316582148],[118.87496812651,32.055181277046],[118.86474423532,32.057294966144],[118.8553692635,32.0551053765],[118.84850506123,32.052078526985],[118.84821923116,32.047026910383]]]}},{"type":"Feature","properties":{"id":61140051,"name":"后宰门","longitude":118.82323526263,"latitude":32.051359466154,"unit_price":31738,"count":"22.00℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.81359387984,32.056031912001],[118.81212358061,32.051625501964],[118.810443,32.046845],[118.82422390595,32.04565953333],[118.829029,32.045269],[118.831473,32.045032],[118.833835,32.044825],[118.83799734125,32.050931600742],[118.83430052,32.054503973949],[118.83482267888,32.057060625279],[118.82621805251,32.059183770191],[118.82592768365,32.057894143474],[118.82385998569,32.058274115007],[118.8237768411,32.057846903038],[118.82008063877,32.058155756073],[118.81641595914,32.05846059464],[118.81423010958,32.058904032724],[118.81359387984,32.056031912001]]]}},{"type":"Feature","properties":{"id":61140053,"name":"卫岗","longitude":118.8547039329,"latitude":32.033963888223,"unit_price":36014,"count":"22.57℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.862461,32.023231],[118.871354,32.026927],[118.877831,32.028993],[118.874229,32.023682],[118.877696,32.021126],[118.876892,32.010204],[118.881595,32.013962],[118.882156,32.014995],[118.881999,32.015841],[118.882987,32.017796],[118.88357971125,32.031357868881],[118.87097744093,32.029542707124],[118.87018737951,32.034647283356],[118.85737007993,32.03447865109],[118.85688145698,32.042621212118],[118.85497288222,32.043158553282],[118.85487677012,32.04550589005],[118.84829294477,32.046924305879],[118.84423,32.047554],[118.842954,32.046085],[118.847985,32.045644],[118.846439,32.0409],[118.845505,32.037839],[118.844544,32.034733],[118.846089,32.034993],[118.847257,32.035039],[118.848838,32.035054],[118.850167,32.035039],[118.850221,32.035085],[118.851533,32.034977],[118.851457,32.028882],[118.852207,32.024757],[118.857026,32.022902],[118.860094,32.022852],[118.862461,32.023231]]]}},{"type":"Feature","properties":{"id":61140055,"name":"南苑","longitude":118.76003420406,"latitude":32.026039845099,"unit_price":31220,"count":"33.42℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.75455515693,32.029572167297],[118.7515099395,32.025063163581],[118.76579269221,32.019028932127],[118.76686882545,32.022478581703],[118.76747374204,32.025062903679],[118.76799035295,32.025658669774],[118.76650221436,32.027906743868],[118.76493308393,32.028717039894],[118.75560048428,32.032838583307],[118.75455515693,32.029572167297],[118.75455515693,32.029572167297]]]}},{"type":"Feature","properties":{"id":61140056,"name":"茶南","longitude":118.7548739659,"latitude":32.038937822905,"unit_price":30714,"count":"27.08℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.75433935967,32.040664328379],[118.75089688215,32.040314713876],[118.75013630831,32.037264174185],[118.75701275897,32.035761979016],[118.75859590942,32.039713803141],[118.76016691509,32.043433366064],[118.756769,32.044264],[118.754317,32.044233],[118.75433935967,32.040664328379]]]}},{"type":"Feature","properties":{"id":61140063,"name":"小行","longitude":118.75775802217,"latitude":31.989271720056,"unit_price":34239,"count":"33.08℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.751371,31.992036],[118.748128,31.988376],[118.75112629952,31.985751925916],[118.75849215222,31.982529436142],[118.76383720699,31.981094893915],[118.770121549,31.981298844896],[118.76934775988,31.986938121979],[118.7605111133,31.994329611078],[118.75991355032,31.994065182748],[118.756563,31.998016],[118.755548,31.998628],[118.753383,31.995467],[118.751371,31.992036]]]}},{"type":"Feature","properties":{"id":61140068,"name":"岔路口","longitude":118.83848513684,"latitude":31.982576589019,"unit_price":26389,"count":"31.53℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.79368746757,31.963359020945],[118.81440272248,31.961449919168],[118.83080867964,31.961756974728],[118.83303548314,31.967341662712],[118.83340557189,31.973789768855],[118.83919030064,31.972409160001],[118.87012742604,31.985513353985],[118.86480388039,31.990456785553],[118.856923,31.997701],[118.851129,31.992557],[118.845327,31.987407],[118.830993,31.986237],[118.826394,31.98492],[118.821809,31.983655],[118.81633,31.98047],[118.78532,31.968341],[118.78564080343,31.968022109478],[118.79219376046,31.96760358451],[118.79368746757,31.963359020945]]]}},{"type":"Feature","properties":{"id":61140070,"name":"东山镇","longitude":118.85883356471,"latitude":31.957229126933,"unit_price":25840,"count":"19.91℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.87021503593,31.985441792025],[118.83915604972,31.972280695203],[118.83348340761,31.973613414754],[118.83316713555,31.967369633166],[118.8309090123,31.961663782062],[118.84250024926,31.935980487355],[118.8528569783,31.938312143366],[118.86997686054,31.943545641988],[118.88609921495,31.946272285465],[118.89253073818,31.948682543491],[118.89967657829,31.951972270225],[118.88766853813,31.960578785918],[118.87916971442,31.971193308836],[118.87021503593,31.985441792025],[118.87021503593,31.985441792025]]]}},{"type":"Feature","properties":{"id":61140080,"name":"长乐路","longitude":118.79316824804,"latitude":32.018144754502,"unit_price":35125,"count":"32.72℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.78271251172,32.015870301606],[118.781661,32.013912],[118.788326,32.012136],[118.80258320402,32.011509778709],[118.80246775905,32.014597852996],[118.80463560173,32.020702043569],[118.80136430656,32.020693981066],[118.78739677733,32.025560427737],[118.78689084959,32.025535850287],[118.78628173434,32.023482875159],[118.78433464393,32.020669823886],[118.78271251172,32.015870301606]]]}},{"type":"Feature","properties":{"id":61140081,"name":"夫子庙","longitude":118.79495200968,"latitude":32.026005906604,"unit_price":36145,"count":"19.14℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.78837372033,32.030010863473],[118.78772786539,32.028406166652],[118.78689301131,32.025537783975],[118.78739515814,32.025563657862],[118.80136728587,32.020690740141],[118.80309448148,32.020760918948],[118.80551532079,32.029429520516],[118.80133263106,32.028962727364],[118.80093912375,32.029974083256],[118.79723071335,32.029791124421],[118.79526665707,32.029437700525],[118.79306062856,32.029058139792],[118.79109453025,32.029132607153],[118.78837372033,32.030010863473],[118.78837372033,32.030010863473]]]}},{"type":"Feature","properties":{"id":61140082,"name":"洪家园","longitude":118.80683324583,"latitude":32.000407176556,"unit_price":30659,"count":"29.90℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.82293653917,32.018532932246],[118.82135155556,32.01294586127],[118.81760211084,32.013368821481],[118.81129411392,32.012333555609],[118.80261492919,32.011438828351],[118.788319,32.012043],[118.788485,32.010362],[118.789029,32.009903],[118.789851,32.009214],[118.790767,32.008273],[118.791863,32.006168],[118.792362,32.005218],[118.792833,32.004273],[118.794437,32.002459],[118.797783,32.000836],[118.799907,31.999741],[118.801089,31.999167],[118.801982,31.998715],[118.80641831999,31.991896632972],[118.810347,31.98681],[118.812763,31.98374],[118.814506,31.982139],[118.816274,31.980597],[118.821679,31.983759],[118.83095,31.986393],[118.845233,31.987572],[118.850945,31.992629],[118.856572,31.997747],[118.85032731043,32.005290223416],[118.83600494768,32.016169377204],[118.83602248426,32.017837371036],[118.83260801814,32.01882209803],[118.82293653917,32.018532932246]]]}},{"type":"Feature","properties":{"id":61140084,"name":"秦虹","longitude":118.81206300944,"latitude":32.017692491722,"unit_price":31752,"count":"32.31℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.80318501498,32.020792945525],[118.80479260522,32.020740822559],[118.80254038521,32.014594871982],[118.8026081193,32.011574970375],[118.81114689293,32.012376828594],[118.81760563854,32.013424121318],[118.8213749601,32.012986513707],[118.82286438362,32.018574914206],[118.81951486554,32.020899317035],[118.81180982408,32.022962156149],[118.81155037967,32.024338945589],[118.81302467861,32.026965496736],[118.81180578729,32.028724656317],[118.81017581807,32.02937843574],[118.8055793454,32.029460503158],[118.80318501498,32.020792945525],[118.80318501498,32.020792945525]]]}},{"type":"Feature","properties":{"id":61140085,"name":"常府街","longitude":118.80234575901,"latitude":32.03655933598,"unit_price":31875,"count":"31.78℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.80118638988,32.035593896564],[118.80338837635,32.035000329647],[118.80684554668,32.034277215054],[118.80675542762,32.035203022181],[118.80776730641,32.038965284613],[118.80294909173,32.03990491071],[118.80126001689,32.040012103299],[118.79904662196,32.040657068541],[118.79762635225,32.036393031507],[118.80118638988,32.035593896564],[118.80118638988,32.035593896564]]]}},{"type":"Feature","properties":{"id":61140093,"name":"铁心桥","longitude":118.750536,"latitude":31.964964,"unit_price":26608,"count":"25.77℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.74819049642,31.988503945487],[118.73991058287,31.979776680137],[118.730588,31.972241],[118.724882,31.963554],[118.72146,31.961226],[118.728976,31.955602],[118.733971,31.953273],[118.738822,31.952814],[118.741014,31.934368],[118.732048,31.931426],[118.733629,31.9245],[118.739594,31.922416],[118.741606,31.924623],[118.750877,31.92119],[118.752889,31.924807],[118.754003,31.9207],[118.761333,31.921252],[118.762052,31.922508],[118.75927076384,31.927134350514],[118.75821215311,31.93088547822],[118.75918132237,31.936583602196],[118.75916140357,31.940825225219],[118.76022118987,31.948219211042],[118.76543262086,31.953394386487],[118.775154,31.960519],[118.775729,31.9647],[118.779897,31.96637],[118.785143,31.968453],[118.78187362434,31.972068653306],[118.78104774426,31.974882173385],[118.7811377048,31.982628854502],[118.77015424593,31.981269591631],[118.76381858838,31.981069127191],[118.75850059888,31.982467153013],[118.75110845171,31.985717406026],[118.74819049642,31.988503945487]]]}},{"type":"Feature","properties":{"id":611100503,"name":"光华路","longitude":118.82254710945,"latitude":32.02297906641,"unit_price":32187,"count":"18.34℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.81159112262,32.02433385888],[118.81183509636,32.022987796885],[118.81952085958,32.020928816532],[118.82291476956,32.018653415757],[118.83260367838,32.018969481472],[118.83623706183,32.017999678255],[118.83679041889,32.025198391637],[118.82269037978,32.026267127822],[118.82210203211,32.02689545607],[118.81182697415,32.028721561307],[118.81307004681,32.026944046342],[118.81159112262,32.02433385888],[118.81159112262,32.02433385888]]]}},{"type":"Feature","properties":{"id":611100551,"name":"凤凰西街","longitude":118.75012580703,"latitude":32.048030037872,"unit_price":56703,"count":"24.39℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.7581488013,32.05163721717],[118.73497863579,32.052475622983],[118.73356236765,32.048822091146],[118.731736,32.046392],[118.733708,32.045363],[118.740832,32.045145],[118.745161,32.045141],[118.747564,32.045153],[118.750322,32.044763],[118.752637,32.044285],[118.753508,32.044288],[118.754361,32.044292],[118.756732,32.044323],[118.760191,32.043489],[118.760488,32.044047],[118.760739,32.04466],[118.760497,32.045731],[118.763034,32.046435],[118.764624,32.046725],[118.764377,32.047858],[118.765419,32.048099],[118.765586,32.047885],[118.766187,32.047961],[118.767526,32.049063],[118.766601,32.049698],[118.76696,32.050004],[118.767364,32.050302],[118.769026,32.049224],[118.770275,32.050203],[118.76988688533,32.050619556547],[118.76558877434,32.054195389157],[118.7623992506,32.051621275871],[118.7581488013,32.05163721717]]]}},{"type":"Feature","properties":{"id":611100558,"name":"应天西路","longitude":118.75564153032,"latitude":32.018385044394,"unit_price":37574,"count":"25.68℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.7420831575,32.019748988299],[118.762186,32.01039],[118.764953,32.014428],[118.766484,32.018844],[118.771546,32.017379],[118.772013,32.019334],[118.772386,32.021301],[118.773612,32.025193],[118.77001950387,32.025225781722],[118.76802437889,32.025661958028],[118.76749128808,32.025047460893],[118.76684742097,32.022277475885],[118.76581078732,32.019014841201],[118.75146820839,32.025043431686],[118.74839026581,32.026364979576],[118.74753161144,32.026614511973],[118.74472326484,32.027351820225],[118.7420831575,32.019748988299]]]}},{"type":"Feature","properties":{"id":611100562,"name":"来凤里","longitude":118.77933602054,"latitude":32.024504817491,"unit_price":31055,"count":"25.42℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.77605665298,32.036036747075],[118.7750600616,32.036206115068],[118.77470257252,32.034148215862],[118.77523220207,32.032205143733],[118.77489178787,32.02944682495],[118.77405834322,32.025210039044],[118.771673,32.017391],[118.774487,32.015716],[118.781583,32.013879],[118.78269496275,32.015913121465],[118.78427415842,32.020661731402],[118.78622720063,32.023541127204],[118.78681548419,32.025519450157],[118.78773300889,32.02842442435],[118.78836535476,32.03002484468],[118.78325532493,32.031739713923],[118.77984030896,32.033628545368],[118.77716701131,32.035723289188],[118.77605665298,32.036036747075]]]}},{"type":"Feature","properties":{"id":611100569,"name":"长江路","longitude":118.79953822463,"latitude":32.051712846052,"unit_price":40666,"count":"33.19℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.790667,32.048098],[118.795873,32.047742],[118.798469,32.047581],[118.799767,32.047501],[118.801065,32.04744],[118.80571,32.04713],[118.808032,32.046988],[118.810354,32.046835],[118.81206895356,32.051603279035],[118.81082749918,32.053168688565],[118.80244740392,32.054755624352],[118.79592528646,32.055991422065],[118.79059352202,32.056549435896],[118.79065,32.052325],[118.790667,32.048098]]]}},{"type":"Feature","properties":{"id":611100572,"name":"宁南","longitude":118.79409310956,"latitude":31.98742420685,"unit_price":34971,"count":"19.58℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.78118969272,31.982741805506],[118.78109822223,31.974884991135],[118.78189547392,31.972091828861],[118.78520008902,31.968447616929],[118.816024,31.980562],[118.812526,31.983596],[118.810092,31.986689],[118.806247,31.99188],[118.801756,31.998594],[118.798612,32.000233],[118.797579,32.000707],[118.79295211126,31.998806228617],[118.78772806369,31.998794200344],[118.78463213925,31.998756632899],[118.78113587449,31.999370173754],[118.78118969272,31.982741805506]]]}},{"type":"Feature","properties":{"id":611100788,"name":"雨花新村","longitude":118.774888906,"latitude":31.997008035393,"unit_price":29243,"count":"31.34℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.76890725951,31.999028077648],[118.76822122291,31.991580103914],[118.7694172539,31.987103680396],[118.77018928475,31.981329876324],[118.78116059802,31.982681612496],[118.78101457438,31.999491096842],[118.78468583477,31.998807722167],[118.79296155489,31.998831023402],[118.797643,32.000748],[118.794337,32.002378],[118.793515,32.003308],[118.792716,32.004242],[118.792199,32.005234],[118.791696,32.00624],[118.790681,32.008234],[118.790133,32.008717],[118.789599,32.009214],[118.789001,32.009769],[118.788395,32.010332],[118.788166,32.012027],[118.78658,32.012395],[118.784945,32.012816],[118.781505,32.013723],[118.77995764063,32.011722458732],[118.77722042869,32.009009473433],[118.77256892502,32.002338077557],[118.77030667995,32.000791095529],[118.76890725951,31.999028077648]]]}},{"type":"Feature","properties":{"id":611100924,"name":"能仁里","longitude":118.76959524643,"latitude":32.008638772722,"unit_price":34997,"count":"27.46℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.766622,32.018739],[118.765126,32.01438],[118.76425,32.013067],[118.763312,32.011735],[118.761439,32.009102],[118.76129,32.007647],[118.761066,32.006201],[118.760217,32.00485],[118.762458,32.004012],[118.76538161714,32.003070211007],[118.76814000066,32.002593670174],[118.77045594722,32.002825195276],[118.77252815994,32.00234519511],[118.77717670158,32.009015706407],[118.77990824845,32.011702831481],[118.781511,32.013775],[118.78064,32.013993],[118.779755,32.014234],[118.777972,32.014697],[118.774419,32.015643],[118.773665,32.016006],[118.772955,32.01645],[118.771545,32.017312],[118.766622,32.018739]]]}},{"type":"Feature","properties":{"id":613000125,"name":"月牙湖","longitude":118.86248564069,"latitude":32.012838811947,"unit_price":29142,"count":"23.37℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.851297,32.028778],[118.851371,32.03484],[118.851353,32.034824],[118.851254,32.034824],[118.849952,32.034855],[118.847697,32.03487],[118.846008,32.034725],[118.844293,32.034518],[118.844625,32.035674],[118.846163,32.040846],[118.847713,32.045467],[118.845247,32.045689],[118.842925,32.04588],[118.837589,32.045808],[118.835959,32.044878],[118.833708,32.044595],[118.83227608716,32.03438191591],[118.83152305281,32.029020019141],[118.82216494795,32.026935837446],[118.82273234181,32.026322971943],[118.83695948895,32.025277186095],[118.83624322904,32.016307639701],[118.85071608933,32.005360515075],[118.856804,31.997946],[118.86231,32.002968],[118.867898,32.007959],[118.871213,32.007132],[118.87283,32.00626],[118.87389,32.00848],[118.876665,32.010087],[118.877088,32.015514],[118.877465,32.021071],[118.873988,32.023681],[118.877438,32.028739],[118.87138867308,32.026827626878],[118.866937,32.024936],[118.862481,32.023076],[118.859948,32.022693],[118.856957,32.02277],[118.852034,32.024698],[118.851297,32.028778]]]}},{"type":"Feature","properties":{"id":613000127,"name":"建康路","longitude":118.80205559249,"latitude":32.032651591842,"unit_price":32947,"count":"24.68℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.79660308798,32.033096154002],[118.7976452903,32.032403619723],[118.79872737759,32.03144968629],[118.80098384762,32.030016643002],[118.80135513613,32.028994309473],[118.80555387396,32.029495210817],[118.8069342875,32.029474519335],[118.80774699643,32.032659052039],[118.80706654,32.032743834777],[118.80683602983,32.034250900469],[118.80345799224,32.03494599438],[118.80110537786,32.035577205606],[118.79762443436,32.036366425295],[118.79660308798,32.033096154002],[118.79660308798,32.033096154002]]]}},{"type":"Feature","properties":{"id":613000133,"name":"五老村","longitude":118.80442082623,"latitude":32.043318716068,"unit_price":38350,"count":"31.86℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.80080267896,32.045960182613],[118.79904909276,32.040692359619],[118.80126491464,32.040034648529],[118.80296970908,32.039925601307],[118.80778849828,32.038992389736],[118.810291,32.046433],[118.809079,32.046559],[118.807897,32.046636],[118.80562,32.046842],[118.801079,32.047198],[118.80080267896,32.045960182613]]]}},{"type":"Feature","properties":{"id":613000134,"name":"升州路","longitude":118.78759483307,"latitude":32.033255485346,"unit_price":41285,"count":"23.14℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.77830325874,32.036602753928],[118.77793870982,32.03515709821],[118.77986919475,32.033633962307],[118.78328557406,32.031754353782],[118.78839967106,32.030034047817],[118.79112643592,32.029151756927],[118.79309038811,32.029085086503],[118.79726402295,32.029823698114],[118.80096216677,32.030001335862],[118.79871761213,32.031423025632],[118.79762768397,32.03238583797],[118.79657466988,32.033088838224],[118.7970492804,32.03472946957],[118.79254903937,32.035202141696],[118.79108144323,32.035485104884],[118.78676263991,32.036501992153],[118.78570534954,32.036558798585],[118.78470974874,32.037502029298],[118.78028992853,32.039358311162],[118.77830325874,32.036602753928],[118.77830325874,32.036602753928]]]}},{"type":"Feature","properties":{"id":613000140,"name":"万达广场","longitude":118.73522484518,"latitude":32.036108142966,"unit_price":45281,"count":"26.43℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.72577593506,32.040971702723],[118.72266632766,32.033997635503],[118.7286749916,32.030814560585],[118.74467552759,32.027402100244],[118.7475112902,32.026648406778],[118.7508573318,32.040325131696],[118.74474170472,32.039814079481],[118.745099,32.04508],[118.740821,32.04508],[118.737246,32.045187],[118.733693,32.045313],[118.732692,32.045815],[118.73169624508,32.046341525444],[118.72577593506,32.040971702723]]]}},{"type":"Feature","properties":{"id":613000141,"name":"江东","longitude":118.74926407734,"latitude":32.042318441966,"unit_price":31154,"count":"27.78℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.7449969922,32.043018174471],[118.74474225408,32.039820861949],[118.75086086889,32.040340069889],[118.75430907202,32.040698836376],[118.754322,32.044239],[118.752637,32.044208],[118.752121,32.044319],[118.751514,32.044457],[118.750396,32.044694],[118.748959,32.044893],[118.747575,32.045088],[118.746371,32.045069],[118.745159,32.045077],[118.7449969922,32.043018174471]]]}},{"type":"Feature","properties":{"id":613000154,"name":"兴隆大街","longitude":118.74921377374,"latitude":32.013081513073,"unit_price":43363,"count":"21.88℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.73858494291,32.023911944837],[118.73393669071,32.01745595388],[118.760025,32.004883],[118.760937,32.006212],[118.761049,32.00705],[118.761166,32.00788],[118.761166,32.007884],[118.7613,32.009159],[118.761705,32.009939],[118.762163,32.01036],[118.74197805261,32.019749450055],[118.74468066389,32.027367362993],[118.73967770517,32.028366399546],[118.73858494291,32.023911944837]]]}},{"type":"Feature","properties":{"id":1100000413,"name":"汉中门大街","longitude":118.765863,"latitude":32.046098,"unit_price":43054,"count":"30.30℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.766694,32.049736],[118.767332,32.050302],[118.768311,32.049839],[118.769133,32.049281],[118.769753,32.04974],[118.770049,32.050008],[118.770328,32.050299],[118.772313,32.048248],[118.77116,32.047687],[118.770992,32.047468],[118.771877,32.046461],[118.771459,32.046278],[118.771051,32.046044],[118.769829,32.045214],[118.767565,32.043546],[118.767287,32.043141],[118.766716,32.043592],[118.766227,32.044112],[118.766092,32.044258],[118.764412,32.043225],[118.760415,32.043512],[118.760307,32.043611],[118.760734,32.044453],[118.760756,32.04474],[118.760734,32.045023],[118.760536,32.04575],[118.76054,32.045765],[118.763015,32.046385],[118.764484,32.04666],[118.764475,32.046641],[118.764551,32.04666],[118.764637,32.04666],[118.76439,32.047869],[118.765436,32.048053],[118.765665,32.047636],[118.765975,32.04777],[118.766568,32.048133],[118.767134,32.048516],[118.767727,32.049017],[118.767848,32.04904],[118.766694,32.049736]]]}},{"type":"Feature","properties":{"id":1100004267,"name":"六合主城","longitude":118.850571,"latitude":32.358223,"unit_price":13150,"count":"32.89℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.84873,32.372793],[118.851541,32.371794],[118.866525,32.367342],[118.862393,32.360175],[118.865735,32.356835],[118.867424,32.35406],[118.862752,32.345412],[118.861639,32.343628],[118.860579,32.341919],[118.859348,32.340463],[118.856177,32.341995],[118.843457,32.346831],[118.83857,32.349759],[118.836055,32.350475],[118.82973,32.351024],[118.839073,32.36481],[118.83857,32.370727],[118.846736,32.373388],[118.84873,32.372793]]]}},{"type":"Feature","properties":{"id":1100004346,"name":"溧水其它","longitude":119.076082,"latitude":31.551583,"unit_price":9626,"count":"29.67℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[119.073508,31.685249],[119.066389,31.691857],[119.064035,31.695099],[119.067934,31.696696],[119.072587,31.699876],[119.074109,31.699913],[119.074109,31.699913],[119.078169,31.703723],[119.078103,31.703793],[119.077522,31.707225],[119.077522,31.707225],[119.075259,31.709099],[119.075259,31.709099],[119.069078,31.710051],[119.069078,31.710051],[119.066204,31.703016],[119.066204,31.703016],[119.060634,31.69979],[119.060634,31.69979],[119.051687,31.711218],[119.051687,31.711218],[119.028439,31.711003],[119.028439,31.711003],[118.996603,31.704552],[118.996603,31.704552],[119.009143,31.693784],[119.009143,31.693784],[119.015809,31.681908],[119.015809,31.681908],[119.016941,31.671736],[119.016941,31.671736],[119.008748,31.673181],[119.008748,31.673181],[119.005029,31.67461],[119.005029,31.67461],[119.00467,31.674625],[119.00467,31.674625],[118.990145,31.671101],[118.982227,31.691427],[118.965837,31.699565],[118.964993,31.700103],[118.96307,31.701163],[118.961975,31.701777],[118.950889,31.709995],[118.949021,31.715616],[118.94223,31.720531],[118.939553,31.726079],[118.939575,31.726125],[118.939521,31.726133],[118.906769,31.74036],[118.906581,31.740467],[118.906931,31.753057],[118.906976,31.75318],[118.901811,31.765123],[118.901819,31.7652],[118.901266,31.773341],[118.901266,31.773341],[118.905781,31.779589],[118.910201,31.785698],[118.910308,31.785797],[118.90953,31.796116],[118.90953,31.796116],[118.918133,31.792235],[118.918178,31.792135],[118.927754,31.784524],[118.927879,31.784447],[118.934827,31.78169],[118.934976,31.781723],[118.935928,31.783426],[118.936,31.783365],[118.959338,31.77322],[118.959536,31.773204],[118.967495,31.774885],[118.967647,31.774885],[118.976738,31.77553],[118.976846,31.775537],[118.979092,31.77464],[118.979244,31.774594],[118.980062,31.773151],[118.98388,31.772015],[118.984032,31.771969],[118.98529,31.776251],[118.985362,31.776382],[118.985353,31.781569],[118.985443,31.781585],[119.011956,31.787386],[119.021249,31.780656],[119.061345,31.794368],[119.120777,31.74568],[119.131233,31.741442],[119.135653,31.729311],[119.145031,31.727837],[119.163752,31.705568],[119.192915,31.699907],[119.196271,31.693217],[119.192502,31.677615],[119.192543,31.677477],[119.199123,31.665338],[119.199257,31.665154],[119.193598,31.655602],[119.19349,31.655503],[119.193526,31.65541],[119.211133,31.652375],[119.21125,31.652298],[119.212732,31.642869],[119.212759,31.642776],[119.218319,31.639149],[119.218319,31.639026],[119.218966,31.633431],[119.219011,31.633346],[119.239007,31.637942],[119.239052,31.637912],[119.240517,31.633008],[119.240418,31.633039],[119.240535,31.632916],[119.240526,31.632854],[119.240571,31.6328],[119.222568,31.591385],[119.222434,31.591124],[119.224158,31.586356],[119.224877,31.584557],[119.222356,31.576095],[119.221976,31.575882],[119.212966,31.568921],[119.21284,31.568437],[119.212094,31.562937],[119.211942,31.562799],[119.204701,31.557991],[119.204593,31.557991],[119.195335,31.557758],[119.195152,31.557714],[119.189053,31.546059],[119.188999,31.545705],[119.189331,31.533672],[119.189681,31.533549],[119.203524,31.52797],[119.203614,31.527878],[119.196015,31.512918],[119.195862,31.512748],[119.190086,31.506476],[119.189906,31.50636],[119.178183,31.504382],[119.177923,31.50409],[119.176219,31.500878],[119.176219,31.500878],[119.159606,31.49961],[119.159427,31.499633],[119.155025,31.493421],[119.154944,31.493298],[119.161825,31.487155],[119.161906,31.486963],[119.162193,31.486785],[119.162274,31.481712],[119.144407,31.447777],[119.151468,31.425802],[119.138361,31.424824],[119.14129,31.443495],[119.138164,31.448008],[119.132801,31.443418],[119.128175,31.428629],[119.122219,31.427381],[119.118985,31.429353],[119.110828,31.425039],[119.107091,31.429369],[119.089269,31.431464],[119.089808,31.438781],[119.07486,31.432188],[119.069003,31.438597],[119.057433,31.430832],[119.05075,31.436255],[119.040707,31.435978],[119.024088,31.420217],[119.02637,31.40715],[119.01656,31.392109],[119.0079,31.389782],[119.001397,31.401433],[118.99421,31.399722],[118.986018,31.390521],[118.976532,31.386791],[118.966812,31.393095],[118.963219,31.40151],[118.953607,31.404931],[118.9466,31.411496],[118.946492,31.418383],[118.938964,31.426426],[118.932964,31.44348],[118.887384,31.493898],[118.892917,31.533595],[118.890546,31.537488],[118.880754,31.53815],[118.879586,31.551106],[118.888695,31.570613],[118.878491,31.580027],[118.884168,31.595776],[118.86904,31.598883],[118.87752,31.604972],[118.875472,31.61715],[118.867208,31.627635],[118.852583,31.644421],[118.882686,31.652649],[118.898882,31.657885],[118.91816,31.685128],[118.943204,31.690751],[118.961992,31.680473],[118.96617,31.650869],[118.963434,31.650308],[118.954047,31.637719],[118.956427,31.621439],[118.971267,31.618795],[118.986431,31.614059],[118.996168,31.614397],[119.007523,31.621408],[119.009014,31.623868],[119.012769,31.620209],[119.011826,31.616104],[119.012697,31.615996],[119.014053,31.61655],[119.015904,31.618041],[119.016209,31.61861],[119.021743,31.617595],[119.024869,31.618149],[119.027438,31.617949],[119.029361,31.616073],[119.03069,31.615797],[119.031948,31.61595],[119.038451,31.615258],[119.042512,31.61326],[119.047345,31.609093],[119.050659,31.608262],[119.052672,31.603188],[119.052636,31.599805],[119.063739,31.603373],[119.077752,31.60817],[119.080555,31.61266],[119.077932,31.618072],[119.07901,31.621301],[119.0738,31.648325],[119.102114,31.657054],[119.084791,31.674617],[119.079549,31.679705],[119.073508,31.685249]]]}},{"type":"Feature","properties":{"id":1100004342,"name":"溧水城北","longitude":119.018197,"latitude":31.694031,"unit_price":10905,"count":"23.06℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.997284,31.70417],[119.009214,31.693847],[119.013166,31.68721],[119.015933,31.681987],[119.017083,31.671723],[119.021682,31.670493],[119.023299,31.668311],[119.031079,31.670601],[119.032929,31.670125],[119.033073,31.67644],[119.037457,31.676486],[119.037906,31.669141],[119.040313,31.668496],[119.050805,31.669618],[119.055261,31.669894],[119.055351,31.669725],[119.063669,31.67183],[119.079479,31.679636],[119.066256,31.691804],[119.051596,31.711097],[119.028456,31.710851],[118.997123,31.704462],[118.997284,31.70417]]]}},{"type":"Feature","properties":{"id":1100004344,"name":"溧水城西","longitude":118.996938,"latitude":31.65207,"unit_price":14941,"count":"28.62℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[119.023096,31.668237],[119.021635,31.670455],[119.016952,31.671617],[119.008616,31.673123],[119.004879,31.674598],[118.997354,31.672806],[118.990177,31.671051],[118.993986,31.661646],[118.966282,31.650262],[118.966179,31.65085],[118.963511,31.650293],[118.954142,31.637744],[118.956514,31.621664],[118.971174,31.618958],[118.98641,31.614284],[118.996039,31.614592],[119.00725,31.621357],[119.008975,31.625477],[119.011203,31.632303],[119.016952,31.636853],[119.023923,31.643063],[119.023324,31.668089],[119.023096,31.668237]]]}},{"type":"Feature","properties":{"id":1100004345,"name":"溧水城中","longitude":119.03541,"latitude":31.657587,"unit_price":11221,"count":"27.54℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[119.023057,31.668012],[119.023923,31.643045],[119.027703,31.647997],[119.047322,31.649042],[119.047501,31.651409],[119.051562,31.651378],[119.051957,31.653222],[119.058568,31.652116],[119.065036,31.652054],[119.065719,31.649257],[119.070354,31.647658],[119.073301,31.648335],[119.101867,31.657064],[119.079585,31.679617],[119.063765,31.67175],[119.055276,31.669644],[119.05516,31.669829],[119.050866,31.669568],[119.040387,31.668436],[119.037831,31.669114],[119.037418,31.676428],[119.033124,31.676413],[119.033021,31.670096],[119.031058,31.670566],[119.023351,31.668269],[119.023057,31.668012]]]}},{"type":"Feature","properties":{"id":1100004343,"name":"溧水城南","longitude":119.045243,"latitude":31.640713,"unit_price":13448,"count":"33.80℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[119.027905,31.647937],[119.024743,31.643449],[119.018312,31.636747],[119.012275,31.632227],[119.010874,31.63026],[119.009257,31.624449],[119.009059,31.624126],[119.013048,31.620221],[119.011934,31.616146],[119.012616,31.6161],[119.013892,31.616562],[119.015796,31.618099],[119.016156,31.618668],[119.021725,31.617653],[119.024887,31.618207],[119.027492,31.618037],[119.029379,31.616177],[119.030618,31.615885],[119.032038,31.616023],[119.038505,31.615378],[119.042692,31.613271],[119.047417,31.609135],[119.05083,31.608428],[119.05286,31.603292],[119.052789,31.599847],[119.077654,31.608089],[119.080456,31.612641],[119.077797,31.617991],[119.078875,31.621312],[119.073629,31.648306],[119.070395,31.647568],[119.06558,31.649136],[119.065113,31.651964],[119.058542,31.652048],[119.051985,31.653001],[119.051751,31.651218],[119.047763,31.651356],[119.047529,31.648859],[119.027892,31.647937],[119.027905,31.647937]]]}},{"type":"Feature","properties":{"id":613000131,"name":"麒麟镇","longitude":118.92428102551,"latitude":32.019652419747,"unit_price":22076,"count":"22.34℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.87882265146,31.972027703848],[118.89768423101,31.981284901542],[118.92023205431,31.993966206127],[118.95092602206,32.029336032547],[118.96671985749,32.058442354037],[118.96962758698,32.068947972825],[118.95573051195,32.072414624103],[118.94114327309,32.074100305056],[118.92508,32.070773],[118.92226,32.051418],[118.908318,32.043384],[118.903297,32.039236],[118.898266,32.033543],[118.89938,32.030949],[118.900449,32.028339],[118.898095,32.027474],[118.896973,32.027757],[118.896254,32.027558],[118.896101,32.027115],[118.895975,32.026808],[118.89549,32.02651],[118.895113,32.026257],[118.890891,32.023893],[118.888681,32.021665],[118.886399,32.019507],[118.883175,32.017708],[118.88224,32.01581],[118.88251,32.014945],[118.882357,32.014341],[118.881872,32.013736],[118.876868,32.009878],[118.87412,32.008263],[118.873149,32.005844],[118.871946,32.006288],[118.87102,32.006939],[118.869727,32.00726],[118.86846,32.007505],[118.865577,32.005002],[118.862621,32.002675],[118.857115,31.997684],[118.87034319418,31.98546964154],[118.87882265146,31.972027703848]]]}},{"type":"Feature","properties":{"id":1100005790,"name":"汤山镇","longitude":119.070476,"latitude":32.047025,"unit_price":16502,"count":"28.15℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[119.106069,32.096352],[119.104468,32.078543],[119.09182,32.057002],[119.10648,32.018067],[119.097017,32.007149],[119.075781,32.011037],[119.0613,32.010272],[119.053,32.009659],[119.044556,32.009169],[119.007186,32.018416],[118.970751,32.027661],[118.998468,32.065203],[119.003554,32.086226],[119.029033,32.092719],[119.059503,32.098837],[119.088537,32.10471],[119.092505,32.09756],[119.097895,32.095205],[119.106069,32.096352]]]}},{"type":"Feature","properties":{"id":611100548,"name":"仙林","longitude":118.94191434643,"latitude":32.120374666241,"unit_price":34944,"count":"28.04℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.95980237258,32.141367587621],[118.94949153998,32.140389044985],[118.91163095136,32.122824697085],[118.899513,32.108987],[118.896231,32.105331],[118.904087,32.100059],[118.911797,32.095153],[118.913091,32.097844],[118.917834,32.094418],[118.914815,32.092522],[118.920808,32.088349],[118.924819,32.085386],[118.926787,32.08316],[118.938186,32.085106],[118.958048,32.106723],[118.971772,32.10735],[118.981115,32.120302],[118.98202592725,32.122669240458],[118.9992801949,32.126118676879],[119.00512704279,32.12660158386],[119.00364005613,32.136750306026],[118.99777635438,32.142488563175],[118.9961655617,32.147308584424],[118.97603550751,32.142974653794],[118.95980237258,32.141367587621]]]}},{"type":"Feature","properties":{"id":1100000895,"name":"仙鹤门","longitude":118.898614,"latitude":32.092393,"unit_price":28238,"count":"29.89℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[118.913796,32.092699],[118.916899,32.094388],[118.913091,32.097171],[118.911905,32.09451],[118.909717,32.095972],[118.896243,32.105164],[118.893099,32.103466],[118.8862,32.101417],[118.882175,32.100392],[118.885122,32.092026],[118.886829,32.088447],[118.892793,32.080232],[118.892793,32.080232],[118.913796,32.092699]]]}},{"type":"Feature","properties":{"id":1100004341,"name":"溧水恒大","longitude":119.071051,"latitude":31.703348,"unit_price":10978,"count":"25.46℃","icon":"icon"},"geometry":{"type":"Polygon","coordinates":[[[119.060541,31.699707],[119.064098,31.695006],[119.067907,31.696727],[119.072524,31.699938],[119.07407,31.70003],[119.078022,31.703747],[119.077411,31.707249],[119.075076,31.709093],[119.069111,31.709953],[119.066344,31.70301],[119.061726,31.700352],[119.060541,31.699707]]]}}]} \ No newline at end of file diff --git a/examples/data/shanghaixi-village.json b/examples/data/shanghaixi-village.json new file mode 100644 index 00000000000..79e82cb123a --- /dev/null +++ b/examples/data/shanghaixi-village.json @@ -0,0 +1,351 @@ +[{ + "id": "5011000000404", + "name": "铁路新村(华池路)", + "longitude": 121.4316962, + "latitude": 31.26082325, + "unit_price": 71469.4, + "count": 2 +}, { + "id": "5011000002716", + "name": "金元坊", + "longitude": 121.3810096, + "latitude": 31.25302026, + "unit_price": 47480.5, + "count": 2 +}, { + "id": "5011000003403", + "name": "兰溪路231弄", + "longitude": 121.4086229, + "latitude": 31.25291206, + "unit_price": 55218.4, + "count": 2 +}, { + "id": "5011000003652", + "name": "兰溪公寓", + "longitude": 121.409227, + "latitude": 31.251014, + "unit_price": 55577.8, + "count": 2 +}, { + "id": "5011000004139", + "name": "梅岭新村", + "longitude": 121.400946, + "latitude": 31.24946565, + "unit_price": 63028.1, + "count": 2 +}, { + "id": "5011000005647", + "name": "石泉路140弄", + "longitude": 121.4318415, + "latitude": 31.25682515, + "unit_price": 52256.3, + "count": 2 +}, { + "id": "5011000006479", + "name": "中山北路2165弄", + "longitude": 121.4350523, + "latitude": 31.25364239, + "unit_price": 55129.4, + "count": 2 +}, { + "id": "5011000008328", + "name": "光新路430弄", + "longitude": 121.4374976, + "latitude": 31.26298493, + "unit_price": 49397.2, + "count": 2 +}, { + "id": "5011000004973", + "name": "旬阳新村", + "longitude": 121.431054, + "latitude": 31.259485, + "unit_price": 58836.4, + "count": 3 +}, { + "id": "5011000005863", + "name": "岚皋路300弄", + "longitude": 121.4290778, + "latitude": 31.2587194, + "unit_price": 56944.2, + "count": 3 +}, { + "id": "5011000006645", + "name": "光复西路145弄", + "longitude": 121.4375783, + "latitude": 31.25329386, + "unit_price": 63652.3, + "count": 3 +}, { + "id": "5011000011530", + "name": "祥和大厦", + "longitude": 121.3839187, + "latitude": 31.25161362, + "unit_price": 41029.4, + "count": 3 +}, { + "id": "5011000013673", + "name": "真光十小区", + "longitude": 121.395288, + "latitude": 31.256758, + "unit_price": 41900.9, + "count": 3 +}, { + "id": "5011000013938", + "name": "真光新秀", + "longitude": 121.396422, + "latitude": 31.260857, + "unit_price": 49490.7, + "count": 3 +}, { + "id": "5011000017097", + "name": "陆三小区", + "longitude": 121.4259304, + "latitude": 31.24930686, + "unit_price": 56632.3, + "count": 3 +}, { + "id": "5011000017118", + "name": "樱花苑", + "longitude": 121.4002071, + "latitude": 31.25485805, + "unit_price": 49650.2, + "count": 3 +}, { + "id": "5011000017635", + "name": "宁馨家园", + "longitude": 121.3988072, + "latitude": 31.25289796, + "unit_price": 61407.7, + "count": 3 +}, { + "id": "5011000020263", + "name": "南大街22弄", + "longitude": 121.4090896, + "latitude": 31.25320726, + "unit_price": 52482.1, + "count": 3 +}, { + "id": "5011000000988", + "name": "芝川新苑", + "longitude": 121.409025, + "latitude": 31.263945, + "unit_price": 59417.8, + "count": 4 +}, { + "id": "5011000007885", + "name": "南大街34弄", + "longitude": 121.4080409, + "latitude": 31.2535179, + "unit_price": 49739.4, + "count": 4 +}, { + "id": "5011000016119", + "name": "万千公寓", + "longitude": 121.4379659, + "latitude": 31.26270913, + "unit_price": 61846.7, + "count": 4 +}, { + "id": "5011000017255", + "name": "上海星港", + "longitude": 121.419023, + "latitude": 31.249904, + "unit_price": 81443.3, + "count": 4 +}, { + "id": "5011000018021", + "name": "中岚大楼", + "longitude": 121.432984, + "latitude": 31.251381, + "unit_price": 52858.6, + "count": 4 +}, { + "id": "5011000018102", + "name": "武宁苑", + "longitude": 121.424577, + "latitude": 31.249765, + "unit_price": 53966.7, + "count": 4 +}, { + "id": "5011000019020", + "name": "天汇国际", + "longitude": 121.4115686, + "latitude": 31.26126002, + "unit_price": 45380, + "count": 4 +}, { + "id": "5011102208410", + "name": "三元及地苑", + "longitude": 121.3760233, + "latitude": 31.26220092, + "unit_price": 47857.5, + "count": 4 +}, { + "id": "5011000001095", + "name": "长征家苑", + "longitude": 121.3949788, + "latitude": 31.25376373, + "unit_price": 58117.4, + "count": 5 +}, { + "id": "5011000009828", + "name": "中环财富杰座", + "longitude": 121.378574, + "latitude": 31.25527816, + "unit_price": 26802.3, + "count": 5 +}, { + "id": "5011000013807", + "name": "华轩大厦", + "longitude": 121.375539, + "latitude": 31.258582, + "unit_price": 23147.8, + "count": 5 +}, { + "id": "5011000014493", + "name": "金莲坊", + "longitude": 121.3802448, + "latitude": 31.24989653, + "unit_price": 48458.5, + "count": 5 +}, { + "id": "5011000017050", + "name": "曹杨家园", + "longitude": 121.4101947, + "latitude": 31.26469667, + "unit_price": 56991.5, + "count": 5 +}, { + "id": "5011000018096", + "name": "颐宁苑", + "longitude": 121.415998, + "latitude": 31.252321, + "unit_price": 62755.7, + "count": 5 +}, { + "id": "5011000018172", + "name": "城公大厦", + "longitude": 121.4383528, + "latitude": 31.26001489, + "unit_price": 56813.7, + "count": 5 +}, { + "id": "509977363956217", + "name": "中骏天悦", + "longitude": 121.409065, + "latitude": 31.260569, + "unit_price": 109279, + "count": 5 +}, { + "id": "5011000015683", + "name": "市政馨苑", + "longitude": 121.420237, + "latitude": 31.259543, + "unit_price": 60397.9, + "count": 6 +}, { + "id": "5011000003824", + "name": "星光域", + "longitude": 121.413902, + "latitude": 31.264414, + "unit_price": 91223.7, + "count": 7 +}, { + "id": "5011000014462", + "name": "大隆花苑", + "longitude": 121.4388425, + "latitude": 31.26340479, + "unit_price": 52720.9, + "count": 7 +}, { + "id": "5011000015186", + "name": "光新三村", + "longitude": 121.43749, + "latitude": 31.263028, + "unit_price": 50524.7, + "count": 7 +}, { + "id": "5011000015629", + "name": "平民后村", + "longitude": 121.43489, + "latitude": 31.256305, + "unit_price": 59470, + "count": 7 +}, { + "id": "5011000015825", + "name": "真光新村", + "longitude": 121.397285, + "latitude": 31.260535, + "unit_price": 48991.6, + "count": 7 +}, { + "id": "5011000018225", + "name": "半岛花园", + "longitude": 121.441891, + "latitude": 31.253607, + "unit_price": 73694.6, + "count": 7 +}, { + "id": "5011000008852", + "name": "真西新村第二小区", + "longitude": 121.402254, + "latitude": 31.251552, + "unit_price": 55383.5, + "count": 8 +}, { + "id": "5011000017348", + "name": "嘉秀坊", + "longitude": 121.3750242, + "latitude": 31.26059388, + "unit_price": 47246.6, + "count": 10 +}, { + "id": "5011000018056", + "name": "真情公寓", + "longitude": 121.3909318, + "latitude": 31.26018159, + "unit_price": 56255.2, + "count": 10 +}, { + "id": "5011000011380", + "name": "清涧七街坊", + "longitude": 121.3922347, + "latitude": 31.2646608, + "unit_price": 46948.6, + "count": 11 +}, { + "id": "5011000015943", + "name": "新体育广场", + "longitude": 121.432549, + "latitude": 31.26324211, + "unit_price": 30852.9, + "count": 11 +}, { + "id": "5011000014039", + "name": "清涧六街坊", + "longitude": 121.395639, + "latitude": 31.263124, + "unit_price": 45790.7, + "count": 12 +}, { + "id": "5011000015761", + "name": "曹杨八村", + "longitude": 121.4120603, + "latitude": 31.25113592, + "unit_price": 50921.7, + "count": 18 +}, { + "id": "5011000017518", + "name": "海棠苑", + "longitude": 121.398276, + "latitude": 31.254232, + "unit_price": 49380.8, + "count": 18 +}, { + "id": "5011000012360", + "name": "嘉善坊", + "longitude": 121.3811297, + "latitude": 31.25881044, + "unit_price": 41048.3, + "count": 20 +}] diff --git a/examples/data/us-states.json b/examples/data/us-states.json new file mode 100644 index 00000000000..327ffe6e35a --- /dev/null +++ b/examples/data/us-states.json @@ -0,0 +1,54 @@ +{"type":"FeatureCollection","features":[ +{"type":"Feature","id":"01","properties":{"name":"Alabama","density":94.65},"geometry":{"type":"Polygon","coordinates":[[[-87.359296,35.00118],[-85.606675,34.984749],[-85.431413,34.124869],[-85.184951,32.859696],[-85.069935,32.580372],[-84.960397,32.421541],[-85.004212,32.322956],[-84.889196,32.262709],[-85.058981,32.13674],[-85.053504,32.01077],[-85.141136,31.840985],[-85.042551,31.539753],[-85.113751,31.27686],[-85.004212,31.003013],[-85.497137,30.997536],[-87.600282,30.997536],[-87.633143,30.86609],[-87.408589,30.674397],[-87.446927,30.510088],[-87.37025,30.427934],[-87.518128,30.280057],[-87.655051,30.247195],[-87.90699,30.411504],[-87.934375,30.657966],[-88.011052,30.685351],[-88.10416,30.499135],[-88.137022,30.318396],[-88.394438,30.367688],[-88.471115,31.895754],[-88.241084,33.796253],[-88.098683,34.891641],[-88.202745,34.995703],[-87.359296,35.00118]]]}}, +{"type":"Feature","id":"02","properties":{"name":"Alaska","density":1.264},"geometry":{"type":"MultiPolygon","coordinates":[[[[-131.602021,55.117982],[-131.569159,55.28229],[-131.355558,55.183705],[-131.38842,55.01392],[-131.645836,55.035827],[-131.602021,55.117982]]],[[[-131.832052,55.42469],[-131.645836,55.304197],[-131.749898,55.128935],[-131.832052,55.189182],[-131.832052,55.42469]]],[[[-132.976733,56.437924],[-132.735747,56.459832],[-132.631685,56.421493],[-132.664547,56.273616],[-132.878148,56.240754],[-133.069841,56.333862],[-132.976733,56.437924]]],[[[-133.595627,56.350293],[-133.162949,56.317431],[-133.05341,56.125739],[-132.620732,55.912138],[-132.472854,55.780691],[-132.4619,55.671152],[-132.357838,55.649245],[-132.341408,55.506844],[-132.166146,55.364444],[-132.144238,55.238474],[-132.029222,55.276813],[-131.97993,55.178228],[-131.958022,54.789365],[-132.029222,54.701734],[-132.308546,54.718165],[-132.385223,54.915335],[-132.483808,54.898904],[-132.686455,55.046781],[-132.746701,54.997489],[-132.916486,55.046781],[-132.889102,54.898904],[-132.73027,54.937242],[-132.626209,54.882473],[-132.675501,54.679826],[-132.867194,54.701734],[-133.157472,54.95915],[-133.239626,55.090597],[-133.223195,55.22752],[-133.453227,55.216566],[-133.453227,55.320628],[-133.277964,55.331582],[-133.102702,55.42469],[-133.17938,55.588998],[-133.387503,55.62186],[-133.420365,55.884753],[-133.497042,56.0162],[-133.639442,55.923092],[-133.694212,56.070969],[-133.546335,56.142169],[-133.666827,56.311955],[-133.595627,56.350293]]],[[[-133.738027,55.556137],[-133.546335,55.490413],[-133.414888,55.572568],[-133.283441,55.534229],[-133.420365,55.386352],[-133.633966,55.430167],[-133.738027,55.556137]]],[[[-133.907813,56.930849],[-134.050213,57.029434],[-133.885905,57.095157],[-133.343688,57.002049],[-133.102702,57.007526],[-132.932917,56.82131],[-132.620732,56.667956],[-132.653593,56.55294],[-132.817901,56.492694],[-133.042456,56.520078],[-133.201287,56.448878],[-133.420365,56.492694],[-133.66135,56.448878],[-133.710643,56.684386],[-133.688735,56.837741],[-133.869474,56.843218],[-133.907813,56.930849]]],[[[-134.115936,56.48174],[-134.25286,56.558417],[-134.400737,56.722725],[-134.417168,56.848695],[-134.296675,56.908941],[-134.170706,56.848695],[-134.143321,56.952757],[-133.748981,56.772017],[-133.710643,56.596755],[-133.847566,56.574848],[-133.935197,56.377678],[-133.836612,56.322908],[-133.957105,56.092877],[-134.110459,56.142169],[-134.132367,55.999769],[-134.230952,56.070969],[-134.291198,56.350293],[-134.115936,56.48174]]],[[[-134.636246,56.28457],[-134.669107,56.169554],[-134.806031,56.235277],[-135.178463,56.67891],[-135.413971,56.810356],[-135.331817,56.914418],[-135.424925,57.166357],[-135.687818,57.369004],[-135.419448,57.566174],[-135.298955,57.48402],[-135.063447,57.418296],[-134.849846,57.407343],[-134.844369,57.248511],[-134.636246,56.728202],[-134.636246,56.28457]]],[[[-134.712923,58.223407],[-134.373353,58.14673],[-134.176183,58.157683],[-134.187137,58.081006],[-133.902336,57.807159],[-134.099505,57.850975],[-134.148798,57.757867],[-133.935197,57.615466],[-133.869474,57.363527],[-134.083075,57.297804],[-134.154275,57.210173],[-134.499322,57.029434],[-134.603384,57.034911],[-134.6472,57.226604],[-134.575999,57.341619],[-134.608861,57.511404],[-134.729354,57.719528],[-134.707446,57.829067],[-134.784123,58.097437],[-134.91557,58.212453],[-134.953908,58.409623],[-134.712923,58.223407]]],[[[-135.857603,57.330665],[-135.715203,57.330665],[-135.567326,57.149926],[-135.633049,57.023957],[-135.857603,56.996572],[-135.824742,57.193742],[-135.857603,57.330665]]],[[[-136.279328,58.206976],[-135.978096,58.201499],[-135.780926,58.28913],[-135.496125,58.168637],[-135.64948,58.037191],[-135.59471,57.987898],[-135.45231,58.135776],[-135.107263,58.086483],[-134.91557,57.976944],[-135.025108,57.779775],[-134.937477,57.763344],[-134.822462,57.500451],[-135.085355,57.462112],[-135.572802,57.675713],[-135.556372,57.456635],[-135.709726,57.369004],[-135.890465,57.407343],[-136.000004,57.544266],[-136.208128,57.637374],[-136.366959,57.829067],[-136.569606,57.916698],[-136.558652,58.075529],[-136.421728,58.130299],[-136.377913,58.267222],[-136.279328,58.206976]]],[[[-147.079854,60.200582],[-147.501579,59.948643],[-147.53444,59.850058],[-147.874011,59.784335],[-147.80281,59.937689],[-147.435855,60.09652],[-147.205824,60.271782],[-147.079854,60.200582]]],[[[-147.561825,60.578491],[-147.616594,60.370367],[-147.758995,60.156767],[-147.956165,60.227967],[-147.791856,60.474429],[-147.561825,60.578491]]],[[[-147.786379,70.245291],[-147.682318,70.201475],[-147.162008,70.15766],[-146.888161,70.185044],[-146.510252,70.185044],[-146.099482,70.146706],[-145.858496,70.168614],[-145.622988,70.08646],[-145.195787,69.993352],[-144.620708,69.971444],[-144.461877,70.026213],[-144.078491,70.059075],[-143.914183,70.130275],[-143.497935,70.141229],[-143.503412,70.091936],[-143.25695,70.119321],[-142.747594,70.042644],[-142.402547,69.916674],[-142.079408,69.856428],[-142.008207,69.801659],[-141.712453,69.790705],[-141.433129,69.697597],[-141.378359,69.63735],[-141.208574,69.686643],[-141.00045,69.648304],[-141.00045,60.304644],[-140.53491,60.22249],[-140.474664,60.310121],[-139.987216,60.184151],[-139.696939,60.342983],[-139.088998,60.359413],[-139.198537,60.091043],[-139.045183,59.997935],[-138.700135,59.910304],[-138.623458,59.767904],[-137.604747,59.242118],[-137.445916,58.908024],[-137.265177,59.001132],[-136.827022,59.159963],[-136.580559,59.16544],[-136.465544,59.285933],[-136.476498,59.466672],[-136.301236,59.466672],[-136.25742,59.625503],[-135.945234,59.663842],[-135.479694,59.800766],[-135.025108,59.565257],[-135.068924,59.422857],[-134.959385,59.280456],[-134.701969,59.247595],[-134.378829,59.033994],[-134.400737,58.973748],[-134.25286,58.858732],[-133.842089,58.727285],[-133.173903,58.152206],[-133.075318,57.998852],[-132.867194,57.845498],[-132.560485,57.505928],[-132.253777,57.21565],[-132.368792,57.095157],[-132.05113,57.051341],[-132.127807,56.876079],[-131.870391,56.804879],[-131.837529,56.602232],[-131.580113,56.613186],[-131.087188,56.405062],[-130.78048,56.366724],[-130.621648,56.268139],[-130.468294,56.240754],[-130.424478,56.142169],[-130.101339,56.114785],[-130.002754,55.994292],[-130.150631,55.769737],[-130.128724,55.583521],[-129.986323,55.276813],[-130.095862,55.200136],[-130.336847,54.920812],[-130.687372,54.718165],[-130.785957,54.822227],[-130.917403,54.789365],[-131.010511,54.997489],[-130.983126,55.08512],[-131.092665,55.189182],[-130.862634,55.298721],[-130.928357,55.337059],[-131.158389,55.200136],[-131.284358,55.287767],[-131.426759,55.238474],[-131.843006,55.457552],[-131.700606,55.698537],[-131.963499,55.616383],[-131.974453,55.49589],[-132.182576,55.588998],[-132.226392,55.704014],[-132.083991,55.829984],[-132.127807,55.955953],[-132.324977,55.851892],[-132.522147,56.076446],[-132.642639,56.032631],[-132.719317,56.218847],[-132.527624,56.339339],[-132.341408,56.339339],[-132.396177,56.487217],[-132.297592,56.67891],[-132.450946,56.673433],[-132.768609,56.837741],[-132.993164,57.034911],[-133.51895,57.177311],[-133.507996,57.577128],[-133.677781,57.62642],[-133.639442,57.790728],[-133.814705,57.834544],[-134.072121,58.053622],[-134.143321,58.168637],[-134.586953,58.206976],[-135.074401,58.502731],[-135.282525,59.192825],[-135.38111,59.033994],[-135.337294,58.891593],[-135.140124,58.617746],[-135.189417,58.573931],[-135.05797,58.349376],[-135.085355,58.201499],[-135.277048,58.234361],[-135.430402,58.398669],[-135.633049,58.426053],[-135.91785,58.382238],[-135.912373,58.617746],[-136.087635,58.814916],[-136.246466,58.75467],[-136.876314,58.962794],[-136.931084,58.902547],[-136.586036,58.836824],[-136.317666,58.672516],[-136.213604,58.667039],[-136.180743,58.535592],[-136.043819,58.382238],[-136.388867,58.294607],[-136.591513,58.349376],[-136.59699,58.212453],[-136.859883,58.316515],[-136.947514,58.393192],[-137.111823,58.393192],[-137.566409,58.590362],[-137.900502,58.765624],[-137.933364,58.869686],[-138.11958,59.02304],[-138.634412,59.132579],[-138.919213,59.247595],[-139.417615,59.379041],[-139.746231,59.505011],[-139.718846,59.641934],[-139.625738,59.598119],[-139.5162,59.68575],[-139.625738,59.88292],[-139.488815,59.992458],[-139.554538,60.041751],[-139.801,59.833627],[-140.315833,59.696704],[-140.92925,59.745996],[-141.444083,59.871966],[-141.46599,59.970551],[-141.706976,59.948643],[-141.964392,60.019843],[-142.539471,60.085566],[-142.873564,60.091043],[-143.623905,60.036274],[-143.892275,59.997935],[-144.231845,60.140336],[-144.65357,60.206059],[-144.785016,60.29369],[-144.834309,60.441568],[-145.124586,60.430614],[-145.223171,60.299167],[-145.738004,60.474429],[-145.820158,60.551106],[-146.351421,60.408706],[-146.608837,60.238921],[-146.718376,60.397752],[-146.608837,60.485383],[-146.455483,60.463475],[-145.951604,60.578491],[-146.017328,60.666122],[-146.252836,60.622307],[-146.345944,60.737322],[-146.565022,60.753753],[-146.784099,61.044031],[-146.866253,60.972831],[-147.172962,60.934492],[-147.271547,60.972831],[-147.375609,60.879723],[-147.758995,60.912584],[-147.775426,60.808523],[-148.032842,60.781138],[-148.153334,60.819476],[-148.065703,61.005692],[-148.175242,61.000215],[-148.350504,60.803046],[-148.109519,60.737322],[-148.087611,60.594922],[-147.939734,60.441568],[-148.027365,60.277259],[-148.219058,60.332029],[-148.273827,60.249875],[-148.087611,60.217013],[-147.983549,59.997935],[-148.251919,59.95412],[-148.399797,59.997935],[-148.635305,59.937689],[-148.755798,59.986981],[-149.067984,59.981505],[-149.05703,60.063659],[-149.204907,60.008889],[-149.287061,59.904827],[-149.418508,59.997935],[-149.582816,59.866489],[-149.511616,59.806242],[-149.741647,59.729565],[-149.949771,59.718611],[-150.031925,59.61455],[-150.25648,59.521442],[-150.409834,59.554303],[-150.579619,59.444764],[-150.716543,59.450241],[-151.001343,59.225687],[-151.308052,59.209256],[-151.406637,59.280456],[-151.592853,59.159963],[-151.976239,59.253071],[-151.888608,59.422857],[-151.636669,59.483103],[-151.47236,59.472149],[-151.423068,59.537872],[-151.127313,59.669319],[-151.116359,59.778858],[-151.505222,59.63098],[-151.828361,59.718611],[-151.8667,59.778858],[-151.702392,60.030797],[-151.423068,60.211536],[-151.379252,60.359413],[-151.297098,60.386798],[-151.264237,60.545629],[-151.406637,60.720892],[-151.06159,60.786615],[-150.404357,61.038554],[-150.245526,60.939969],[-150.042879,60.912584],[-149.741647,61.016646],[-150.075741,61.15357],[-150.207187,61.257632],[-150.47008,61.246678],[-150.656296,61.29597],[-150.711066,61.252155],[-151.023251,61.180954],[-151.165652,61.044031],[-151.477837,61.011169],[-151.800977,60.852338],[-151.833838,60.748276],[-152.080301,60.693507],[-152.13507,60.578491],[-152.310332,60.507291],[-152.392486,60.304644],[-152.732057,60.173197],[-152.567748,60.069136],[-152.704672,59.915781],[-153.022334,59.888397],[-153.049719,59.691227],[-153.345474,59.620026],[-153.438582,59.702181],[-153.586459,59.548826],[-153.761721,59.543349],[-153.72886,59.433811],[-154.117723,59.368087],[-154.1944,59.066856],[-153.750768,59.050425],[-153.400243,58.968271],[-153.301658,58.869686],[-153.444059,58.710854],[-153.679567,58.612269],[-153.898645,58.606793],[-153.920553,58.519161],[-154.062953,58.4863],[-153.99723,58.376761],[-154.145107,58.212453],[-154.46277,58.059098],[-154.643509,58.059098],[-154.818771,58.004329],[-154.988556,58.015283],[-155.120003,57.955037],[-155.081664,57.872883],[-155.328126,57.829067],[-155.377419,57.708574],[-155.547204,57.785251],[-155.73342,57.549743],[-156.045606,57.566174],[-156.023698,57.440204],[-156.209914,57.473066],[-156.34136,57.418296],[-156.34136,57.248511],[-156.549484,56.985618],[-156.883577,56.952757],[-157.157424,56.832264],[-157.20124,56.766541],[-157.376502,56.859649],[-157.672257,56.607709],[-157.754411,56.67891],[-157.918719,56.657002],[-157.957058,56.514601],[-158.126843,56.459832],[-158.32949,56.48174],[-158.488321,56.339339],[-158.208997,56.295524],[-158.510229,55.977861],[-159.375585,55.873799],[-159.616571,55.594475],[-159.676817,55.654722],[-159.643955,55.829984],[-159.813741,55.857368],[-160.027341,55.791645],[-160.060203,55.720445],[-160.394296,55.605429],[-160.536697,55.473983],[-160.580512,55.567091],[-160.668143,55.457552],[-160.865313,55.528752],[-161.232268,55.358967],[-161.506115,55.364444],[-161.467776,55.49589],[-161.588269,55.62186],[-161.697808,55.517798],[-161.686854,55.408259],[-162.053809,55.074166],[-162.179779,55.15632],[-162.218117,55.03035],[-162.470057,55.052258],[-162.508395,55.249428],[-162.661749,55.293244],[-162.716519,55.222043],[-162.579595,55.134412],[-162.645319,54.997489],[-162.847965,54.926289],[-163.00132,55.079643],[-163.187536,55.090597],[-163.220397,55.03035],[-163.034181,54.942719],[-163.373752,54.800319],[-163.14372,54.76198],[-163.138243,54.696257],[-163.329936,54.74555],[-163.587352,54.614103],[-164.085754,54.61958],[-164.332216,54.531949],[-164.354124,54.466226],[-164.638925,54.389548],[-164.847049,54.416933],[-164.918249,54.603149],[-164.710125,54.663395],[-164.551294,54.88795],[-164.34317,54.893427],[-163.894061,55.041304],[-163.532583,55.046781],[-163.39566,54.904381],[-163.291598,55.008443],[-163.313505,55.128935],[-163.105382,55.183705],[-162.880827,55.183705],[-162.579595,55.446598],[-162.245502,55.682106],[-161.807347,55.89023],[-161.292514,55.983338],[-161.078914,55.939523],[-160.87079,55.999769],[-160.816021,55.912138],[-160.931036,55.813553],[-160.805067,55.736876],[-160.766728,55.857368],[-160.509312,55.868322],[-160.438112,55.791645],[-160.27928,55.76426],[-160.273803,55.857368],[-160.536697,55.939523],[-160.558604,55.994292],[-160.383342,56.251708],[-160.147834,56.399586],[-159.830171,56.541986],[-159.326293,56.667956],[-158.959338,56.848695],[-158.784076,56.782971],[-158.641675,56.810356],[-158.701922,56.925372],[-158.658106,57.034911],[-158.378782,57.264942],[-157.995396,57.41282],[-157.688688,57.609989],[-157.705118,57.719528],[-157.458656,58.497254],[-157.07527,58.705377],[-157.119086,58.869686],[-158.039212,58.634177],[-158.32949,58.661562],[-158.40069,58.760147],[-158.564998,58.803962],[-158.619768,58.913501],[-158.767645,58.864209],[-158.860753,58.694424],[-158.701922,58.480823],[-158.893615,58.387715],[-159.0634,58.420577],[-159.392016,58.760147],[-159.616571,58.929932],[-159.731586,58.929932],[-159.808264,58.803962],[-159.906848,58.782055],[-160.054726,58.886116],[-160.235465,58.902547],[-160.317619,59.072332],[-160.854359,58.88064],[-161.33633,58.743716],[-161.374669,58.667039],[-161.752577,58.552023],[-161.938793,58.656085],[-161.769008,58.776578],[-161.829255,59.061379],[-161.955224,59.36261],[-161.703285,59.48858],[-161.911409,59.740519],[-162.092148,59.88292],[-162.234548,60.091043],[-162.448149,60.178674],[-162.502918,59.997935],[-162.760334,59.959597],[-163.171105,59.844581],[-163.66403,59.795289],[-163.9324,59.806242],[-164.162431,59.866489],[-164.189816,60.02532],[-164.386986,60.074613],[-164.699171,60.29369],[-164.962064,60.337506],[-165.268773,60.578491],[-165.060649,60.68803],[-165.016834,60.890677],[-165.175665,60.846861],[-165.197573,60.972831],[-165.120896,61.076893],[-165.323543,61.170001],[-165.34545,61.071416],[-165.591913,61.109754],[-165.624774,61.279539],[-165.816467,61.301447],[-165.920529,61.416463],[-165.915052,61.558863],[-166.106745,61.49314],[-166.139607,61.630064],[-165.904098,61.662925],[-166.095791,61.81628],[-165.756221,61.827233],[-165.756221,62.013449],[-165.674067,62.139419],[-165.044219,62.539236],[-164.912772,62.659728],[-164.819664,62.637821],[-164.874433,62.807606],[-164.633448,63.097884],[-164.425324,63.212899],[-164.036462,63.262192],[-163.73523,63.212899],[-163.313505,63.037637],[-163.039658,63.059545],[-162.661749,63.22933],[-162.272887,63.486746],[-162.075717,63.514131],[-162.026424,63.448408],[-161.555408,63.448408],[-161.13916,63.503177],[-160.766728,63.771547],[-160.766728,63.837271],[-160.952944,64.08921],[-160.974852,64.237087],[-161.26513,64.395918],[-161.374669,64.532842],[-161.078914,64.494503],[-160.79959,64.609519],[-160.783159,64.719058],[-161.144637,64.921705],[-161.413007,64.762873],[-161.664946,64.790258],[-161.900455,64.702627],[-162.168825,64.680719],[-162.234548,64.620473],[-162.541257,64.532842],[-162.634365,64.384965],[-162.787719,64.324718],[-162.858919,64.49998],[-163.045135,64.538319],[-163.176582,64.401395],[-163.253259,64.467119],[-163.598306,64.565704],[-164.304832,64.560227],[-164.80871,64.450688],[-165.000403,64.434257],[-165.411174,64.49998],[-166.188899,64.576658],[-166.391546,64.636904],[-166.484654,64.735489],[-166.413454,64.872412],[-166.692778,64.987428],[-166.638008,65.113398],[-166.462746,65.179121],[-166.517516,65.337952],[-166.796839,65.337952],[-167.026871,65.381768],[-167.47598,65.414629],[-167.711489,65.496784],[-168.072967,65.578938],[-168.105828,65.682999],[-167.541703,65.819923],[-166.829701,66.049954],[-166.3313,66.186878],[-166.046499,66.110201],[-165.756221,66.09377],[-165.690498,66.203309],[-165.86576,66.21974],[-165.88219,66.312848],[-165.186619,66.466202],[-164.403417,66.581218],[-163.981692,66.592172],[-163.751661,66.553833],[-163.872153,66.389525],[-163.828338,66.274509],[-163.915969,66.192355],[-163.768091,66.060908],[-163.494244,66.082816],[-163.149197,66.060908],[-162.749381,66.088293],[-162.634365,66.039001],[-162.371472,66.028047],[-162.14144,66.077339],[-161.840208,66.02257],[-161.549931,66.241647],[-161.341807,66.252601],[-161.199406,66.208786],[-161.128206,66.334755],[-161.528023,66.395002],[-161.911409,66.345709],[-161.87307,66.510017],[-162.174302,66.68528],[-162.502918,66.740049],[-162.601503,66.89888],[-162.344087,66.937219],[-162.015471,66.778388],[-162.075717,66.652418],[-161.916886,66.553833],[-161.571838,66.438817],[-161.489684,66.55931],[-161.884024,66.718141],[-161.714239,67.002942],[-161.851162,67.052235],[-162.240025,66.991988],[-162.639842,67.008419],[-162.700088,67.057712],[-162.902735,67.008419],[-163.740707,67.128912],[-163.757138,67.254881],[-164.009077,67.534205],[-164.211724,67.638267],[-164.534863,67.725898],[-165.192096,67.966884],[-165.493328,68.059992],[-165.794559,68.081899],[-166.243668,68.246208],[-166.681824,68.339316],[-166.703731,68.372177],[-166.375115,68.42147],[-166.227238,68.574824],[-166.216284,68.881533],[-165.329019,68.859625],[-164.255539,68.930825],[-163.976215,68.985595],[-163.532583,69.138949],[-163.110859,69.374457],[-163.023228,69.609966],[-162.842489,69.812613],[-162.470057,69.982398],[-162.311225,70.108367],[-161.851162,70.311014],[-161.779962,70.256245],[-161.396576,70.239814],[-160.837928,70.343876],[-160.487404,70.453415],[-159.649432,70.792985],[-159.33177,70.809416],[-159.298908,70.760123],[-158.975769,70.798462],[-158.658106,70.787508],[-158.033735,70.831323],[-157.420318,70.979201],[-156.812377,71.285909],[-156.565915,71.351633],[-156.522099,71.296863],[-155.585543,71.170894],[-155.508865,71.083263],[-155.832005,70.968247],[-155.979882,70.96277],[-155.974405,70.809416],[-155.503388,70.858708],[-155.476004,70.940862],[-155.262403,71.017539],[-155.191203,70.973724],[-155.032372,71.148986],[-154.566832,70.990155],[-154.643509,70.869662],[-154.353231,70.8368],[-154.183446,70.7656],[-153.931507,70.880616],[-153.487874,70.886093],[-153.235935,70.924431],[-152.589656,70.886093],[-152.26104,70.842277],[-152.419871,70.606769],[-151.817408,70.546523],[-151.773592,70.486276],[-151.187559,70.382214],[-151.182082,70.431507],[-150.760358,70.49723],[-150.355064,70.491753],[-150.349588,70.436984],[-150.114079,70.431507],[-149.867617,70.508184],[-149.462323,70.519138],[-149.177522,70.486276],[-148.78866,70.404122],[-148.607921,70.420553],[-148.350504,70.305537],[-148.202627,70.349353],[-147.961642,70.316491],[-147.786379,70.245291]]],[[[-152.94018,58.026237],[-152.945657,57.982421],[-153.290705,58.048145],[-153.044242,58.305561],[-152.819688,58.327469],[-152.666333,58.562977],[-152.496548,58.354853],[-152.354148,58.426053],[-152.080301,58.311038],[-152.080301,58.152206],[-152.480117,58.130299],[-152.655379,58.059098],[-152.94018,58.026237]]],[[[-153.958891,57.538789],[-153.67409,57.670236],[-153.931507,57.69762],[-153.936983,57.812636],[-153.723383,57.889313],[-153.570028,57.834544],[-153.548121,57.719528],[-153.46049,57.796205],[-153.455013,57.96599],[-153.268797,57.889313],[-153.235935,57.998852],[-153.071627,57.933129],[-152.874457,57.933129],[-152.721103,57.993375],[-152.469163,57.889313],[-152.469163,57.599035],[-152.151501,57.620943],[-152.359625,57.42925],[-152.74301,57.505928],[-152.60061,57.379958],[-152.710149,57.275896],[-152.907319,57.325188],[-152.912796,57.128019],[-153.214027,57.073249],[-153.312612,56.991095],[-153.498828,57.067772],[-153.695998,56.859649],[-153.849352,56.837741],[-154.013661,56.744633],[-154.073907,56.969187],[-154.303938,56.848695],[-154.314892,56.919895],[-154.523016,56.991095],[-154.539447,57.193742],[-154.742094,57.275896],[-154.627078,57.511404],[-154.227261,57.659282],[-153.980799,57.648328],[-153.958891,57.538789]]],[[[-154.53397,56.602232],[-154.742094,56.399586],[-154.807817,56.432447],[-154.53397,56.602232]]],[[[-155.634835,55.923092],[-155.476004,55.912138],[-155.530773,55.704014],[-155.793666,55.731399],[-155.837482,55.802599],[-155.634835,55.923092]]],[[[-159.890418,55.28229],[-159.950664,55.068689],[-160.257373,54.893427],[-160.109495,55.161797],[-160.005433,55.134412],[-159.890418,55.28229]]],[[[-160.520266,55.358967],[-160.33405,55.358967],[-160.339527,55.249428],[-160.525743,55.128935],[-160.690051,55.211089],[-160.794113,55.134412],[-160.854359,55.320628],[-160.79959,55.380875],[-160.520266,55.358967]]],[[[-162.256456,54.981058],[-162.234548,54.893427],[-162.349564,54.838658],[-162.437195,54.931766],[-162.256456,54.981058]]],[[[-162.415287,63.634624],[-162.563165,63.536039],[-162.612457,63.62367],[-162.415287,63.634624]]],[[[-162.80415,54.488133],[-162.590549,54.449795],[-162.612457,54.367641],[-162.782242,54.373118],[-162.80415,54.488133]]],[[[-165.548097,54.29644],[-165.476897,54.181425],[-165.630251,54.132132],[-165.685021,54.252625],[-165.548097,54.29644]]],[[[-165.73979,54.15404],[-166.046499,54.044501],[-166.112222,54.121178],[-165.980775,54.219763],[-165.73979,54.15404]]],[[[-166.364161,60.359413],[-166.13413,60.397752],[-166.084837,60.326552],[-165.88219,60.342983],[-165.685021,60.277259],[-165.646682,59.992458],[-165.750744,59.89935],[-166.00816,59.844581],[-166.062929,59.745996],[-166.440838,59.855535],[-166.6161,59.850058],[-166.994009,59.992458],[-167.125456,59.992458],[-167.344534,60.074613],[-167.421211,60.206059],[-167.311672,60.238921],[-166.93924,60.206059],[-166.763978,60.310121],[-166.577762,60.321075],[-166.495608,60.392275],[-166.364161,60.359413]]],[[[-166.375115,54.01164],[-166.210807,53.934962],[-166.5449,53.748746],[-166.539423,53.715885],[-166.117699,53.852808],[-166.112222,53.776131],[-166.282007,53.683023],[-166.555854,53.622777],[-166.583239,53.529669],[-166.878994,53.431084],[-167.13641,53.425607],[-167.306195,53.332499],[-167.623857,53.250345],[-167.793643,53.337976],[-167.459549,53.442038],[-167.355487,53.425607],[-167.103548,53.513238],[-167.163794,53.611823],[-167.021394,53.715885],[-166.807793,53.666592],[-166.785886,53.732316],[-167.015917,53.754223],[-167.141887,53.825424],[-167.032348,53.945916],[-166.643485,54.017116],[-166.561331,53.880193],[-166.375115,54.01164]]],[[[-168.790446,53.157237],[-168.40706,53.34893],[-168.385152,53.431084],[-168.237275,53.524192],[-168.007243,53.568007],[-167.886751,53.518715],[-167.842935,53.387268],[-168.270136,53.244868],[-168.500168,53.036744],[-168.686384,52.965544],[-168.790446,53.157237]]],[[[-169.74891,52.894344],[-169.705095,52.795759],[-169.962511,52.790282],[-169.989896,52.856005],[-169.74891,52.894344]]],[[[-170.148727,57.221127],[-170.28565,57.128019],[-170.313035,57.221127],[-170.148727,57.221127]]],[[[-170.669036,52.697174],[-170.603313,52.604066],[-170.789529,52.538343],[-170.816914,52.636928],[-170.669036,52.697174]]],[[[-171.742517,63.716778],[-170.94836,63.5689],[-170.488297,63.69487],[-170.280174,63.683916],[-170.093958,63.612716],[-170.044665,63.492223],[-169.644848,63.4265],[-169.518879,63.366254],[-168.99857,63.338869],[-168.686384,63.295053],[-168.856169,63.147176],[-169.108108,63.180038],[-169.376478,63.152653],[-169.513402,63.08693],[-169.639372,62.939052],[-169.831064,63.075976],[-170.055619,63.169084],[-170.263743,63.180038],[-170.362328,63.2841],[-170.866206,63.415546],[-171.101715,63.421023],[-171.463193,63.306007],[-171.73704,63.366254],[-171.852055,63.486746],[-171.742517,63.716778]]],[[[-172.432611,52.390465],[-172.41618,52.275449],[-172.607873,52.253542],[-172.569535,52.352127],[-172.432611,52.390465]]],[[[-173.626584,52.14948],[-173.495138,52.105664],[-173.122706,52.111141],[-173.106275,52.07828],[-173.549907,52.028987],[-173.626584,52.14948]]],[[[-174.322156,52.280926],[-174.327632,52.379511],[-174.185232,52.41785],[-173.982585,52.319265],[-174.059262,52.226157],[-174.179755,52.231634],[-174.141417,52.127572],[-174.333109,52.116618],[-174.738403,52.007079],[-174.968435,52.039941],[-174.902711,52.116618],[-174.656249,52.105664],[-174.322156,52.280926]]],[[[-176.469116,51.853725],[-176.288377,51.870156],[-176.288377,51.744186],[-176.518409,51.760617],[-176.80321,51.61274],[-176.912748,51.80991],[-176.792256,51.815386],[-176.775825,51.963264],[-176.627947,51.968741],[-176.627947,51.859202],[-176.469116,51.853725]]],[[[-177.153734,51.946833],[-177.044195,51.897541],[-177.120872,51.727755],[-177.274226,51.678463],[-177.279703,51.782525],[-177.153734,51.946833]]],[[[-178.123152,51.919448],[-177.953367,51.913971],[-177.800013,51.793479],[-177.964321,51.651078],[-178.123152,51.919448]]],[[[-187.107557,52.992929],[-187.293773,52.927205],[-187.304726,52.823143],[-188.90491,52.762897],[-188.642017,52.927205],[-188.642017,53.003883],[-187.107557,52.992929]]]]}}, +{"type":"Feature","id":"04","properties":{"name":"Arizona","density":57.05},"geometry":{"type":"Polygon","coordinates":[[[-109.042503,37.000263],[-109.04798,31.331629],[-111.074448,31.331629],[-112.246513,31.704061],[-114.815198,32.492741],[-114.72209,32.717295],[-114.524921,32.755634],[-114.470151,32.843265],[-114.524921,33.029481],[-114.661844,33.034958],[-114.727567,33.40739],[-114.524921,33.54979],[-114.497536,33.697668],[-114.535874,33.933176],[-114.415382,34.108438],[-114.256551,34.174162],[-114.136058,34.305608],[-114.333228,34.448009],[-114.470151,34.710902],[-114.634459,34.87521],[-114.634459,35.00118],[-114.574213,35.138103],[-114.596121,35.324319],[-114.678275,35.516012],[-114.738521,36.102045],[-114.371566,36.140383],[-114.251074,36.01989],[-114.152489,36.025367],[-114.048427,36.195153],[-114.048427,37.000263],[-110.499369,37.00574],[-109.042503,37.000263]]]}}, +{"type":"Feature","id":"05","properties":{"name":"Arkansas","density":56.43},"geometry":{"type":"Polygon","coordinates":[[[-94.473842,36.501861],[-90.152536,36.496384],[-90.064905,36.304691],[-90.218259,36.184199],[-90.377091,35.997983],[-89.730812,35.997983],[-89.763673,35.811767],[-89.911551,35.756997],[-89.944412,35.603643],[-90.130628,35.439335],[-90.114197,35.198349],[-90.212782,35.023087],[-90.311367,34.995703],[-90.251121,34.908072],[-90.409952,34.831394],[-90.481152,34.661609],[-90.585214,34.617794],[-90.568783,34.420624],[-90.749522,34.365854],[-90.744046,34.300131],[-90.952169,34.135823],[-90.891923,34.026284],[-91.072662,33.867453],[-91.231493,33.560744],[-91.056231,33.429298],[-91.143862,33.347144],[-91.089093,33.13902],[-91.16577,33.002096],[-93.608485,33.018527],[-94.041164,33.018527],[-94.041164,33.54979],[-94.183564,33.593606],[-94.380734,33.544313],[-94.484796,33.637421],[-94.430026,35.395519],[-94.616242,36.501861],[-94.473842,36.501861]]]}}, +{"type":"Feature","id":"06","properties":{"name":"California","density":241.7},"geometry":{"type":"Polygon","coordinates":[[[-123.233256,42.006186],[-122.378853,42.011663],[-121.037003,41.995232],[-120.001861,41.995232],[-119.996384,40.264519],[-120.001861,38.999346],[-118.71478,38.101128],[-117.498899,37.21934],[-116.540435,36.501861],[-115.85034,35.970598],[-114.634459,35.00118],[-114.634459,34.87521],[-114.470151,34.710902],[-114.333228,34.448009],[-114.136058,34.305608],[-114.256551,34.174162],[-114.415382,34.108438],[-114.535874,33.933176],[-114.497536,33.697668],[-114.524921,33.54979],[-114.727567,33.40739],[-114.661844,33.034958],[-114.524921,33.029481],[-114.470151,32.843265],[-114.524921,32.755634],[-114.72209,32.717295],[-116.04751,32.624187],[-117.126467,32.536556],[-117.24696,32.668003],[-117.252437,32.876127],[-117.329114,33.122589],[-117.471515,33.297851],[-117.7837,33.538836],[-118.183517,33.763391],[-118.260194,33.703145],[-118.413548,33.741483],[-118.391641,33.840068],[-118.566903,34.042715],[-118.802411,33.998899],[-119.218659,34.146777],[-119.278905,34.26727],[-119.558229,34.415147],[-119.875891,34.40967],[-120.138784,34.475393],[-120.472878,34.448009],[-120.64814,34.579455],[-120.609801,34.858779],[-120.670048,34.902595],[-120.631709,35.099764],[-120.894602,35.247642],[-120.905556,35.450289],[-121.004141,35.461243],[-121.168449,35.636505],[-121.283465,35.674843],[-121.332757,35.784382],[-121.716143,36.195153],[-121.896882,36.315645],[-121.935221,36.638785],[-121.858544,36.6114],[-121.787344,36.803093],[-121.929744,36.978355],[-122.105006,36.956447],[-122.335038,37.115279],[-122.417192,37.241248],[-122.400761,37.361741],[-122.515777,37.520572],[-122.515777,37.783465],[-122.329561,37.783465],[-122.406238,38.15042],[-122.488392,38.112082],[-122.504823,37.931343],[-122.701993,37.893004],[-122.937501,38.029928],[-122.97584,38.265436],[-123.129194,38.451652],[-123.331841,38.566668],[-123.44138,38.698114],[-123.737134,38.95553],[-123.687842,39.032208],[-123.824765,39.366301],[-123.764519,39.552517],[-123.85215,39.831841],[-124.109566,40.105688],[-124.361506,40.259042],[-124.410798,40.439781],[-124.158859,40.877937],[-124.109566,41.025814],[-124.158859,41.14083],[-124.065751,41.442061],[-124.147905,41.715908],[-124.257444,41.781632],[-124.213628,42.000709],[-123.233256,42.006186]]]}}, +{"type":"Feature","id":"08","properties":{"name":"Colorado","density":49.33},"geometry":{"type":"Polygon","coordinates":[[[-107.919731,41.003906],[-105.728954,40.998429],[-104.053011,41.003906],[-102.053927,41.003906],[-102.053927,40.001626],[-102.042974,36.994786],[-103.001438,37.000263],[-104.337812,36.994786],[-106.868158,36.994786],[-107.421329,37.000263],[-109.042503,37.000263],[-109.042503,38.166851],[-109.058934,38.27639],[-109.053457,39.125316],[-109.04798,40.998429],[-107.919731,41.003906]]]}}, +{"type":"Feature","id":"09","properties":{"name":"Connecticut","density":739.1},"geometry":{"type":"Polygon","coordinates":[[[-73.053528,42.039048],[-71.799309,42.022617],[-71.799309,42.006186],[-71.799309,41.414677],[-71.859555,41.321569],[-71.947186,41.338],[-72.385341,41.261322],[-72.905651,41.28323],[-73.130205,41.146307],[-73.371191,41.102491],[-73.655992,40.987475],[-73.727192,41.102491],[-73.48073,41.21203],[-73.55193,41.294184],[-73.486206,42.050002],[-73.053528,42.039048]]]}}, +{"type":"Feature","id":"10","properties":{"name":"Delaware","density":464.3},"geometry":{"type":"Polygon","coordinates":[[[-75.414089,39.804456],[-75.507197,39.683964],[-75.611259,39.61824],[-75.589352,39.459409],[-75.441474,39.311532],[-75.403136,39.065069],[-75.189535,38.807653],[-75.09095,38.796699],[-75.047134,38.451652],[-75.693413,38.462606],[-75.786521,39.722302],[-75.616736,39.831841],[-75.414089,39.804456]]]}}, +{"type":"Feature","id":"11","properties":{"name":"District of Columbia","density":10065},"geometry":{"type":"Polygon","coordinates":[[[-77.035264,38.993869],[-76.909294,38.895284],[-77.040741,38.791222],[-77.117418,38.933623],[-77.035264,38.993869]]]}}, +{"type":"Feature","id":"12","properties":{"name":"Florida","density":353.4},"geometry":{"type":"Polygon","coordinates":[[[-85.497137,30.997536],[-85.004212,31.003013],[-84.867289,30.712735],[-83.498053,30.647012],[-82.216449,30.570335],[-82.167157,30.356734],[-82.046664,30.362211],[-82.002849,30.564858],[-82.041187,30.751074],[-81.948079,30.827751],[-81.718048,30.745597],[-81.444201,30.707258],[-81.383954,30.27458],[-81.257985,29.787132],[-80.967707,29.14633],[-80.524075,28.461713],[-80.589798,28.41242],[-80.56789,28.094758],[-80.381674,27.738757],[-80.091397,27.021277],[-80.03115,26.796723],[-80.036627,26.566691],[-80.146166,25.739673],[-80.239274,25.723243],[-80.337859,25.465826],[-80.304997,25.383672],[-80.49669,25.197456],[-80.573367,25.241272],[-80.759583,25.164595],[-81.077246,25.120779],[-81.170354,25.224841],[-81.126538,25.378195],[-81.351093,25.821827],[-81.526355,25.903982],[-81.679709,25.843735],[-81.800202,26.090198],[-81.833064,26.292844],[-82.041187,26.517399],[-82.09048,26.665276],[-82.057618,26.878877],[-82.172634,26.917216],[-82.145249,26.791246],[-82.249311,26.758384],[-82.566974,27.300601],[-82.692943,27.437525],[-82.391711,27.837342],[-82.588881,27.815434],[-82.720328,27.689464],[-82.851774,27.886634],[-82.676512,28.434328],[-82.643651,28.888914],[-82.764143,28.998453],[-82.802482,29.14633],[-82.994175,29.179192],[-83.218729,29.420177],[-83.399469,29.518762],[-83.410422,29.66664],[-83.536392,29.721409],[-83.640454,29.885717],[-84.02384,30.104795],[-84.357933,30.055502],[-84.341502,29.902148],[-84.451041,29.929533],[-84.867289,29.743317],[-85.310921,29.699501],[-85.299967,29.80904],[-85.404029,29.940487],[-85.924338,30.236241],[-86.29677,30.362211],[-86.630863,30.395073],[-86.910187,30.373165],[-87.518128,30.280057],[-87.37025,30.427934],[-87.446927,30.510088],[-87.408589,30.674397],[-87.633143,30.86609],[-87.600282,30.997536],[-85.497137,30.997536]]]}}, +{"type":"Feature","id":"13","properties":{"name":"Georgia","density":169.5},"geometry":{"type":"Polygon","coordinates":[[[-83.109191,35.00118],[-83.322791,34.787579],[-83.339222,34.683517],[-83.005129,34.469916],[-82.901067,34.486347],[-82.747713,34.26727],[-82.714851,34.152254],[-82.55602,33.94413],[-82.325988,33.81816],[-82.194542,33.631944],[-81.926172,33.462159],[-81.937125,33.347144],[-81.761863,33.160928],[-81.493493,33.007573],[-81.42777,32.843265],[-81.416816,32.629664],[-81.279893,32.558464],[-81.121061,32.290094],[-81.115584,32.120309],[-80.885553,32.032678],[-81.132015,31.693108],[-81.175831,31.517845],[-81.279893,31.364491],[-81.290846,31.20566],[-81.400385,31.13446],[-81.444201,30.707258],[-81.718048,30.745597],[-81.948079,30.827751],[-82.041187,30.751074],[-82.002849,30.564858],[-82.046664,30.362211],[-82.167157,30.356734],[-82.216449,30.570335],[-83.498053,30.647012],[-84.867289,30.712735],[-85.004212,31.003013],[-85.113751,31.27686],[-85.042551,31.539753],[-85.141136,31.840985],[-85.053504,32.01077],[-85.058981,32.13674],[-84.889196,32.262709],[-85.004212,32.322956],[-84.960397,32.421541],[-85.069935,32.580372],[-85.184951,32.859696],[-85.431413,34.124869],[-85.606675,34.984749],[-84.319594,34.990226],[-83.618546,34.984749],[-83.109191,35.00118]]]}}, +{"type":"Feature","id":"15","properties":{"name":"Hawaii","density":214.1},"geometry":{"type":"MultiPolygon","coordinates":[[[[-155.634835,18.948267],[-155.881297,19.035898],[-155.919636,19.123529],[-155.886774,19.348084],[-156.062036,19.73147],[-155.925113,19.857439],[-155.826528,20.032702],[-155.897728,20.147717],[-155.87582,20.26821],[-155.596496,20.12581],[-155.284311,20.021748],[-155.092618,19.868393],[-155.092618,19.736947],[-154.807817,19.523346],[-154.983079,19.348084],[-155.295265,19.26593],[-155.514342,19.134483],[-155.634835,18.948267]]],[[[-156.587823,21.029505],[-156.472807,20.892581],[-156.324929,20.952827],[-156.00179,20.793996],[-156.051082,20.651596],[-156.379699,20.580396],[-156.445422,20.60778],[-156.461853,20.783042],[-156.631638,20.821381],[-156.697361,20.919966],[-156.587823,21.029505]]],[[[-156.982162,21.210244],[-157.080747,21.106182],[-157.310779,21.106182],[-157.239579,21.221198],[-156.982162,21.210244]]],[[[-157.951581,21.697691],[-157.842042,21.462183],[-157.896811,21.325259],[-158.110412,21.303352],[-158.252813,21.582676],[-158.126843,21.588153],[-157.951581,21.697691]]],[[[-159.468693,22.228955],[-159.353678,22.218001],[-159.298908,22.113939],[-159.33177,21.966061],[-159.446786,21.872953],[-159.764448,21.987969],[-159.726109,22.152277],[-159.468693,22.228955]]]]}}, +{"type":"Feature","id":"16","properties":{"name":"Idaho","density":19.15},"geometry":{"type":"Polygon","coordinates":[[[-116.04751,49.000239],[-116.04751,47.976051],[-115.724371,47.696727],[-115.718894,47.42288],[-115.527201,47.302388],[-115.324554,47.258572],[-115.302646,47.187372],[-114.930214,46.919002],[-114.886399,46.809463],[-114.623506,46.705401],[-114.612552,46.639678],[-114.322274,46.645155],[-114.464674,46.272723],[-114.492059,46.037214],[-114.387997,45.88386],[-114.568736,45.774321],[-114.497536,45.670259],[-114.546828,45.560721],[-114.333228,45.456659],[-114.086765,45.593582],[-113.98818,45.703121],[-113.807441,45.604536],[-113.834826,45.522382],[-113.736241,45.330689],[-113.571933,45.128042],[-113.45144,45.056842],[-113.456917,44.865149],[-113.341901,44.782995],[-113.133778,44.772041],[-113.002331,44.448902],[-112.887315,44.394132],[-112.783254,44.48724],[-112.471068,44.481763],[-112.241036,44.569394],[-112.104113,44.520102],[-111.868605,44.563917],[-111.819312,44.509148],[-111.616665,44.547487],[-111.386634,44.75561],[-111.227803,44.580348],[-111.047063,44.476286],[-111.047063,42.000709],[-112.164359,41.995232],[-114.04295,41.995232],[-117.027882,42.000709],[-117.027882,43.830007],[-116.896436,44.158624],[-116.97859,44.240778],[-117.170283,44.257209],[-117.241483,44.394132],[-117.038836,44.750133],[-116.934774,44.782995],[-116.830713,44.930872],[-116.847143,45.02398],[-116.732128,45.144473],[-116.671881,45.319735],[-116.463758,45.61549],[-116.545912,45.752413],[-116.78142,45.823614],[-116.918344,45.993399],[-116.92382,46.168661],[-117.055267,46.343923],[-117.038836,46.426077],[-117.044313,47.762451],[-117.033359,49.000239],[-116.04751,49.000239]]]}}, +{"type":"Feature","id":"17","properties":{"name":"Illinois","density":231.5},"geometry":{"type":"Polygon","coordinates":[[[-90.639984,42.510065],[-88.788778,42.493634],[-87.802929,42.493634],[-87.83579,42.301941],[-87.682436,42.077386],[-87.523605,41.710431],[-87.529082,39.34987],[-87.63862,39.169131],[-87.512651,38.95553],[-87.49622,38.780268],[-87.62219,38.637868],[-87.655051,38.506421],[-87.83579,38.292821],[-87.950806,38.27639],[-87.923421,38.15042],[-88.000098,38.101128],[-88.060345,37.865619],[-88.027483,37.799896],[-88.15893,37.657496],[-88.065822,37.482234],[-88.476592,37.389126],[-88.514931,37.285064],[-88.421823,37.153617],[-88.547792,37.071463],[-88.914747,37.224817],[-89.029763,37.213863],[-89.183118,37.038601],[-89.133825,36.983832],[-89.292656,36.994786],[-89.517211,37.279587],[-89.435057,37.34531],[-89.517211,37.537003],[-89.517211,37.690357],[-89.84035,37.903958],[-89.949889,37.88205],[-90.059428,38.013497],[-90.355183,38.216144],[-90.349706,38.374975],[-90.179921,38.632391],[-90.207305,38.725499],[-90.10872,38.845992],[-90.251121,38.917192],[-90.470199,38.961007],[-90.585214,38.867899],[-90.661891,38.928146],[-90.727615,39.256762],[-91.061708,39.470363],[-91.368417,39.727779],[-91.494386,40.034488],[-91.50534,40.237135],[-91.417709,40.379535],[-91.401278,40.560274],[-91.121954,40.669813],[-91.09457,40.823167],[-90.963123,40.921752],[-90.946692,41.097014],[-91.111001,41.239415],[-91.045277,41.414677],[-90.656414,41.463969],[-90.344229,41.589939],[-90.311367,41.743293],[-90.179921,41.809016],[-90.141582,42.000709],[-90.168967,42.126679],[-90.393521,42.225264],[-90.420906,42.329326],[-90.639984,42.510065]]]}}, +{"type":"Feature","id":"18","properties":{"name":"Indiana","density":181.7},"geometry":{"type":"Polygon","coordinates":[[[-85.990061,41.759724],[-84.807042,41.759724],[-84.807042,41.694001],[-84.801565,40.500028],[-84.817996,39.103408],[-84.894673,39.059592],[-84.812519,38.785745],[-84.987781,38.780268],[-85.173997,38.68716],[-85.431413,38.730976],[-85.42046,38.533806],[-85.590245,38.451652],[-85.655968,38.325682],[-85.83123,38.27639],[-85.924338,38.024451],[-86.039354,37.958727],[-86.263908,38.051835],[-86.302247,38.166851],[-86.521325,38.040881],[-86.504894,37.931343],[-86.729448,37.893004],[-86.795172,37.991589],[-87.047111,37.893004],[-87.129265,37.788942],[-87.381204,37.93682],[-87.512651,37.903958],[-87.600282,37.975158],[-87.682436,37.903958],[-87.934375,37.893004],[-88.027483,37.799896],[-88.060345,37.865619],[-88.000098,38.101128],[-87.923421,38.15042],[-87.950806,38.27639],[-87.83579,38.292821],[-87.655051,38.506421],[-87.62219,38.637868],[-87.49622,38.780268],[-87.512651,38.95553],[-87.63862,39.169131],[-87.529082,39.34987],[-87.523605,41.710431],[-87.42502,41.644708],[-87.118311,41.644708],[-86.822556,41.759724],[-85.990061,41.759724]]]}}, +{"type":"Feature","id":"19","properties":{"name":"Iowa","density":54.81},"geometry":{"type":"Polygon","coordinates":[[[-91.368417,43.501391],[-91.215062,43.501391],[-91.204109,43.353514],[-91.056231,43.254929],[-91.176724,43.134436],[-91.143862,42.909881],[-91.067185,42.75105],[-90.711184,42.636034],[-90.639984,42.510065],[-90.420906,42.329326],[-90.393521,42.225264],[-90.168967,42.126679],[-90.141582,42.000709],[-90.179921,41.809016],[-90.311367,41.743293],[-90.344229,41.589939],[-90.656414,41.463969],[-91.045277,41.414677],[-91.111001,41.239415],[-90.946692,41.097014],[-90.963123,40.921752],[-91.09457,40.823167],[-91.121954,40.669813],[-91.401278,40.560274],[-91.417709,40.379535],[-91.527248,40.412397],[-91.729895,40.615043],[-91.833957,40.609566],[-93.257961,40.582182],[-94.632673,40.571228],[-95.7664,40.587659],[-95.881416,40.719105],[-95.826646,40.976521],[-95.925231,41.201076],[-95.919754,41.453015],[-96.095016,41.540646],[-96.122401,41.67757],[-96.062155,41.798063],[-96.127878,41.973325],[-96.264801,42.039048],[-96.44554,42.488157],[-96.631756,42.707235],[-96.544125,42.855112],[-96.511264,43.052282],[-96.434587,43.123482],[-96.560556,43.222067],[-96.527695,43.397329],[-96.582464,43.479483],[-96.451017,43.501391],[-91.368417,43.501391]]]}}, +{"type":"Feature","id":"20","properties":{"name":"Kansas","density":35.09},"geometry":{"type":"Polygon","coordinates":[[[-101.90605,40.001626],[-95.306337,40.001626],[-95.207752,39.908518],[-94.884612,39.831841],[-95.109167,39.541563],[-94.983197,39.442978],[-94.824366,39.20747],[-94.610765,39.158177],[-94.616242,37.000263],[-100.087706,37.000263],[-102.042974,36.994786],[-102.053927,40.001626],[-101.90605,40.001626]]]}}, +{"type":"Feature","id":"21","properties":{"name":"Kentucky","density":110},"geometry":{"type":"Polygon","coordinates":[[[-83.903347,38.769315],[-83.678792,38.632391],[-83.519961,38.703591],[-83.142052,38.626914],[-83.032514,38.725499],[-82.890113,38.758361],[-82.846298,38.588575],[-82.731282,38.561191],[-82.594358,38.424267],[-82.621743,38.123036],[-82.50125,37.931343],[-82.342419,37.783465],[-82.293127,37.668449],[-82.101434,37.553434],[-81.969987,37.537003],[-82.353373,37.268633],[-82.720328,37.120755],[-82.720328,37.044078],[-82.868205,36.978355],[-82.879159,36.890724],[-83.070852,36.852385],[-83.136575,36.742847],[-83.673316,36.600446],[-83.689746,36.584015],[-84.544149,36.594969],[-85.289013,36.627831],[-85.486183,36.616877],[-86.592525,36.655216],[-87.852221,36.633308],[-88.071299,36.677123],[-88.054868,36.496384],[-89.298133,36.507338],[-89.418626,36.496384],[-89.363857,36.622354],[-89.215979,36.578538],[-89.133825,36.983832],[-89.183118,37.038601],[-89.029763,37.213863],[-88.914747,37.224817],[-88.547792,37.071463],[-88.421823,37.153617],[-88.514931,37.285064],[-88.476592,37.389126],[-88.065822,37.482234],[-88.15893,37.657496],[-88.027483,37.799896],[-87.934375,37.893004],[-87.682436,37.903958],[-87.600282,37.975158],[-87.512651,37.903958],[-87.381204,37.93682],[-87.129265,37.788942],[-87.047111,37.893004],[-86.795172,37.991589],[-86.729448,37.893004],[-86.504894,37.931343],[-86.521325,38.040881],[-86.302247,38.166851],[-86.263908,38.051835],[-86.039354,37.958727],[-85.924338,38.024451],[-85.83123,38.27639],[-85.655968,38.325682],[-85.590245,38.451652],[-85.42046,38.533806],[-85.431413,38.730976],[-85.173997,38.68716],[-84.987781,38.780268],[-84.812519,38.785745],[-84.894673,39.059592],[-84.817996,39.103408],[-84.43461,39.103408],[-84.231963,38.895284],[-84.215533,38.807653],[-83.903347,38.769315]]]}}, +{"type":"Feature","id":"22","properties":{"name":"Louisiana","density":105},"geometry":{"type":"Polygon","coordinates":[[[-93.608485,33.018527],[-91.16577,33.002096],[-91.072662,32.887081],[-91.143862,32.843265],[-91.154816,32.640618],[-91.006939,32.514649],[-90.985031,32.218894],[-91.105524,31.988862],[-91.341032,31.846462],[-91.401278,31.621907],[-91.499863,31.643815],[-91.516294,31.27686],[-91.636787,31.265906],[-91.565587,31.068736],[-91.636787,30.997536],[-89.747242,30.997536],[-89.845827,30.66892],[-89.681519,30.449842],[-89.643181,30.285534],[-89.522688,30.181472],[-89.818443,30.044549],[-89.84035,29.945964],[-89.599365,29.88024],[-89.495303,30.039072],[-89.287179,29.88024],[-89.30361,29.754271],[-89.424103,29.699501],[-89.648657,29.748794],[-89.621273,29.655686],[-89.69795,29.513285],[-89.506257,29.387316],[-89.199548,29.348977],[-89.09001,29.2011],[-89.002379,29.179192],[-89.16121,29.009407],[-89.336472,29.042268],[-89.484349,29.217531],[-89.851304,29.310638],[-89.851304,29.480424],[-90.032043,29.425654],[-90.021089,29.283254],[-90.103244,29.151807],[-90.23469,29.129899],[-90.333275,29.277777],[-90.563307,29.283254],[-90.645461,29.129899],[-90.798815,29.086084],[-90.963123,29.179192],[-91.09457,29.190146],[-91.220539,29.436608],[-91.445094,29.546147],[-91.532725,29.529716],[-91.620356,29.73784],[-91.883249,29.710455],[-91.888726,29.836425],[-92.146142,29.715932],[-92.113281,29.622824],[-92.31045,29.535193],[-92.617159,29.579009],[-92.97316,29.715932],[-93.2251,29.776178],[-93.767317,29.726886],[-93.838517,29.688547],[-93.926148,29.787132],[-93.690639,30.143133],[-93.767317,30.334826],[-93.696116,30.438888],[-93.728978,30.575812],[-93.630393,30.679874],[-93.526331,30.93729],[-93.542762,31.15089],[-93.816609,31.556184],[-93.822086,31.775262],[-94.041164,31.994339],[-94.041164,33.018527],[-93.608485,33.018527]]]}}, +{"type":"Feature","id":"23","properties":{"name":"Maine","density":43.04},"geometry":{"type":"Polygon","coordinates":[[[-70.703921,43.057759],[-70.824413,43.128959],[-70.807983,43.227544],[-70.966814,43.34256],[-71.032537,44.657025],[-71.08183,45.303304],[-70.649151,45.440228],[-70.720352,45.511428],[-70.556043,45.664782],[-70.386258,45.735983],[-70.41912,45.796229],[-70.260289,45.889337],[-70.309581,46.064599],[-70.210996,46.327492],[-70.057642,46.415123],[-69.997395,46.694447],[-69.225147,47.461219],[-69.044408,47.428357],[-69.033454,47.242141],[-68.902007,47.176418],[-68.578868,47.285957],[-68.376221,47.285957],[-68.233821,47.357157],[-67.954497,47.198326],[-67.790188,47.066879],[-67.779235,45.944106],[-67.801142,45.675736],[-67.456095,45.604536],[-67.505388,45.48952],[-67.417757,45.379982],[-67.488957,45.281397],[-67.346556,45.128042],[-67.16034,45.160904],[-66.979601,44.804903],[-67.187725,44.646072],[-67.308218,44.706318],[-67.406803,44.596779],[-67.549203,44.624164],[-67.565634,44.531056],[-67.75185,44.54201],[-68.047605,44.328409],[-68.118805,44.476286],[-68.222867,44.48724],[-68.173574,44.328409],[-68.403606,44.251732],[-68.458375,44.377701],[-68.567914,44.311978],[-68.82533,44.311978],[-68.830807,44.459856],[-68.984161,44.426994],[-68.956777,44.322932],[-69.099177,44.103854],[-69.071793,44.043608],[-69.258008,43.923115],[-69.444224,43.966931],[-69.553763,43.840961],[-69.707118,43.82453],[-69.833087,43.720469],[-69.986442,43.742376],[-70.030257,43.851915],[-70.254812,43.676653],[-70.194565,43.567114],[-70.358873,43.528776],[-70.369827,43.435668],[-70.556043,43.320652],[-70.703921,43.057759]]]}}, +{"type":"Feature","id":"24","properties":{"name":"Maryland","density":596.3},"geometry":{"type":"MultiPolygon","coordinates":[[[[-75.994645,37.95325],[-76.016553,37.95325],[-76.043938,37.95325],[-75.994645,37.95325]]],[[[-79.477979,39.722302],[-75.786521,39.722302],[-75.693413,38.462606],[-75.047134,38.451652],[-75.244304,38.029928],[-75.397659,38.013497],[-75.671506,37.95325],[-75.885106,37.909435],[-75.879629,38.073743],[-75.961783,38.139466],[-75.846768,38.210667],[-76.000122,38.374975],[-76.049415,38.303775],[-76.257538,38.320205],[-76.328738,38.500944],[-76.263015,38.500944],[-76.257538,38.736453],[-76.191815,38.829561],[-76.279446,39.147223],[-76.169907,39.333439],[-76.000122,39.366301],[-75.972737,39.557994],[-76.098707,39.536086],[-76.104184,39.437501],[-76.367077,39.311532],[-76.443754,39.196516],[-76.460185,38.906238],[-76.55877,38.769315],[-76.514954,38.539283],[-76.383508,38.380452],[-76.399939,38.259959],[-76.317785,38.139466],[-76.3616,38.057312],[-76.591632,38.216144],[-76.920248,38.292821],[-77.018833,38.446175],[-77.205049,38.358544],[-77.276249,38.479037],[-77.128372,38.632391],[-77.040741,38.791222],[-76.909294,38.895284],[-77.035264,38.993869],[-77.117418,38.933623],[-77.248864,39.026731],[-77.456988,39.076023],[-77.456988,39.223901],[-77.566527,39.306055],[-77.719881,39.322485],[-77.834897,39.601809],[-78.004682,39.601809],[-78.174467,39.694917],[-78.267575,39.61824],[-78.431884,39.623717],[-78.470222,39.514178],[-78.765977,39.585379],[-78.963147,39.437501],[-79.094593,39.470363],[-79.291763,39.300578],[-79.488933,39.20747],[-79.477979,39.722302]]]]}}, +{"type":"Feature","id":"25","properties":{"name":"Massachusetts","density":840.2},"geometry":{"type":"Polygon","coordinates":[[[-70.917521,42.887974],[-70.818936,42.871543],[-70.780598,42.696281],[-70.824413,42.55388],[-70.983245,42.422434],[-70.988722,42.269079],[-70.769644,42.247172],[-70.638197,42.08834],[-70.660105,41.962371],[-70.550566,41.929509],[-70.539613,41.814493],[-70.260289,41.715908],[-69.937149,41.809016],[-70.008349,41.672093],[-70.484843,41.5516],[-70.660105,41.546123],[-70.764167,41.639231],[-70.928475,41.611847],[-70.933952,41.540646],[-71.120168,41.496831],[-71.196845,41.67757],[-71.22423,41.710431],[-71.328292,41.781632],[-71.383061,42.01714],[-71.530939,42.01714],[-71.799309,42.006186],[-71.799309,42.022617],[-73.053528,42.039048],[-73.486206,42.050002],[-73.508114,42.08834],[-73.267129,42.745573],[-72.456542,42.729142],[-71.29543,42.696281],[-71.185891,42.789389],[-70.917521,42.887974]]]}}, +{"type":"Feature","id":"26","properties":{"name":"Michigan","density":173.9},"geometry":{"type":"MultiPolygon","coordinates":[[[[-83.454238,41.732339],[-84.807042,41.694001],[-84.807042,41.759724],[-85.990061,41.759724],[-86.822556,41.759724],[-86.619909,41.891171],[-86.482986,42.115725],[-86.357016,42.252649],[-86.263908,42.444341],[-86.209139,42.718189],[-86.231047,43.013943],[-86.526801,43.594499],[-86.433693,43.813577],[-86.499417,44.07647],[-86.269385,44.34484],[-86.220093,44.569394],[-86.252954,44.689887],[-86.088646,44.73918],[-86.066738,44.903488],[-85.809322,44.947303],[-85.612152,45.128042],[-85.628583,44.766564],[-85.524521,44.750133],[-85.393075,44.930872],[-85.387598,45.237581],[-85.305444,45.314258],[-85.031597,45.363551],[-85.119228,45.577151],[-84.938489,45.75789],[-84.713934,45.768844],[-84.461995,45.653829],[-84.215533,45.637398],[-84.09504,45.494997],[-83.908824,45.484043],[-83.596638,45.352597],[-83.4871,45.358074],[-83.317314,45.144473],[-83.454238,45.029457],[-83.322791,44.88158],[-83.273499,44.711795],[-83.333745,44.339363],[-83.536392,44.246255],[-83.585684,44.054562],[-83.82667,43.988839],[-83.958116,43.758807],[-83.908824,43.671176],[-83.667839,43.589022],[-83.481623,43.714992],[-83.262545,43.972408],[-82.917498,44.070993],[-82.747713,43.994316],[-82.643651,43.851915],[-82.539589,43.435668],[-82.523158,43.227544],[-82.413619,42.975605],[-82.517681,42.614127],[-82.681989,42.559357],[-82.687466,42.690804],[-82.797005,42.652465],[-82.922975,42.351234],[-83.125621,42.236218],[-83.185868,42.006186],[-83.437807,41.814493],[-83.454238,41.732339]]],[[[-85.508091,45.730506],[-85.49166,45.610013],[-85.623106,45.588105],[-85.568337,45.75789],[-85.508091,45.730506]]],[[[-87.589328,45.095181],[-87.742682,45.199243],[-87.649574,45.341643],[-87.885083,45.363551],[-87.791975,45.500474],[-87.781021,45.675736],[-87.989145,45.796229],[-88.10416,45.922199],[-88.531362,46.020784],[-88.662808,45.987922],[-89.09001,46.135799],[-90.119674,46.338446],[-90.229213,46.508231],[-90.415429,46.568478],[-90.026566,46.672539],[-89.851304,46.793032],[-89.413149,46.842325],[-89.128348,46.990202],[-88.996902,46.995679],[-88.887363,47.099741],[-88.575177,47.247618],[-88.416346,47.373588],[-88.180837,47.455742],[-87.956283,47.384542],[-88.350623,47.077833],[-88.443731,46.973771],[-88.438254,46.787555],[-88.246561,46.929956],[-87.901513,46.908048],[-87.633143,46.809463],[-87.392158,46.535616],[-87.260711,46.486323],[-87.008772,46.530139],[-86.948526,46.469893],[-86.696587,46.437031],[-86.159846,46.667063],[-85.880522,46.68897],[-85.508091,46.678016],[-85.256151,46.754694],[-85.064458,46.760171],[-85.02612,46.480847],[-84.82895,46.442508],[-84.63178,46.486323],[-84.549626,46.4206],[-84.418179,46.502754],[-84.127902,46.530139],[-84.122425,46.179615],[-83.990978,46.031737],[-83.793808,45.993399],[-83.7719,46.091984],[-83.580208,46.091984],[-83.476146,45.987922],[-83.563777,45.911245],[-84.111471,45.976968],[-84.374364,45.933153],[-84.659165,46.053645],[-84.741319,45.944106],[-84.70298,45.850998],[-84.82895,45.872906],[-85.015166,46.00983],[-85.338305,46.091984],[-85.502614,46.097461],[-85.661445,45.966014],[-85.924338,45.933153],[-86.209139,45.960537],[-86.324155,45.905768],[-86.351539,45.796229],[-86.663725,45.703121],[-86.647294,45.834568],[-86.784218,45.861952],[-86.838987,45.725029],[-87.069019,45.719552],[-87.17308,45.659305],[-87.326435,45.423797],[-87.611236,45.122565],[-87.589328,45.095181]]],[[[-88.805209,47.976051],[-89.057148,47.850082],[-89.188594,47.833651],[-89.177641,47.937713],[-88.547792,48.173221],[-88.668285,48.008913],[-88.805209,47.976051]]]]}}, +{"type":"Feature","id":"27","properties":{"name":"Minnesota","density":67.14},"geometry":{"type":"Polygon","coordinates":[[[-92.014696,46.705401],[-92.091373,46.749217],[-92.29402,46.667063],[-92.29402,46.075553],[-92.354266,46.015307],[-92.639067,45.933153],[-92.869098,45.719552],[-92.885529,45.577151],[-92.770513,45.566198],[-92.644544,45.440228],[-92.75956,45.286874],[-92.737652,45.117088],[-92.808852,44.750133],[-92.545959,44.569394],[-92.337835,44.552964],[-92.233773,44.443425],[-91.927065,44.333886],[-91.877772,44.202439],[-91.592971,44.032654],[-91.43414,43.994316],[-91.242447,43.775238],[-91.269832,43.616407],[-91.215062,43.501391],[-91.368417,43.501391],[-96.451017,43.501391],[-96.451017,45.297827],[-96.681049,45.412843],[-96.856311,45.604536],[-96.582464,45.818137],[-96.560556,45.933153],[-96.598895,46.332969],[-96.719387,46.437031],[-96.801542,46.656109],[-96.785111,46.924479],[-96.823449,46.968294],[-96.856311,47.609096],[-97.053481,47.948667],[-97.130158,48.140359],[-97.16302,48.545653],[-97.097296,48.682577],[-97.228743,49.000239],[-95.152983,49.000239],[-95.152983,49.383625],[-94.955813,49.372671],[-94.824366,49.295994],[-94.69292,48.775685],[-94.588858,48.715438],[-94.260241,48.699007],[-94.221903,48.649715],[-93.838517,48.627807],[-93.794701,48.518268],[-93.466085,48.545653],[-93.466085,48.589469],[-93.208669,48.644238],[-92.984114,48.62233],[-92.726698,48.540176],[-92.655498,48.436114],[-92.50762,48.447068],[-92.370697,48.222514],[-92.304974,48.315622],[-92.053034,48.359437],[-92.009219,48.266329],[-91.713464,48.200606],[-91.713464,48.112975],[-91.565587,48.041775],[-91.264355,48.080113],[-91.083616,48.178698],[-90.837154,48.238944],[-90.749522,48.091067],[-90.579737,48.123929],[-90.377091,48.091067],[-90.141582,48.112975],[-89.873212,47.987005],[-89.615796,48.008913],[-89.637704,47.954144],[-89.971797,47.828174],[-90.437337,47.729589],[-90.738569,47.625527],[-91.171247,47.368111],[-91.357463,47.20928],[-91.642264,47.028541],[-92.091373,46.787555],[-92.014696,46.705401]]]}}, +{"type":"Feature","id":"28","properties":{"name":"Mississippi","density":63.50},"geometry":{"type":"Polygon","coordinates":[[[-88.471115,34.995703],[-88.202745,34.995703],[-88.098683,34.891641],[-88.241084,33.796253],[-88.471115,31.895754],[-88.394438,30.367688],[-88.503977,30.323872],[-88.744962,30.34578],[-88.843547,30.411504],[-89.084533,30.367688],[-89.418626,30.252672],[-89.522688,30.181472],[-89.643181,30.285534],[-89.681519,30.449842],[-89.845827,30.66892],[-89.747242,30.997536],[-91.636787,30.997536],[-91.565587,31.068736],[-91.636787,31.265906],[-91.516294,31.27686],[-91.499863,31.643815],[-91.401278,31.621907],[-91.341032,31.846462],[-91.105524,31.988862],[-90.985031,32.218894],[-91.006939,32.514649],[-91.154816,32.640618],[-91.143862,32.843265],[-91.072662,32.887081],[-91.16577,33.002096],[-91.089093,33.13902],[-91.143862,33.347144],[-91.056231,33.429298],[-91.231493,33.560744],[-91.072662,33.867453],[-90.891923,34.026284],[-90.952169,34.135823],[-90.744046,34.300131],[-90.749522,34.365854],[-90.568783,34.420624],[-90.585214,34.617794],[-90.481152,34.661609],[-90.409952,34.831394],[-90.251121,34.908072],[-90.311367,34.995703],[-88.471115,34.995703]]]}}, +{"type":"Feature","id":"29","properties":{"name":"Missouri","density":87.26},"geometry":{"type":"Polygon","coordinates":[[[-91.833957,40.609566],[-91.729895,40.615043],[-91.527248,40.412397],[-91.417709,40.379535],[-91.50534,40.237135],[-91.494386,40.034488],[-91.368417,39.727779],[-91.061708,39.470363],[-90.727615,39.256762],[-90.661891,38.928146],[-90.585214,38.867899],[-90.470199,38.961007],[-90.251121,38.917192],[-90.10872,38.845992],[-90.207305,38.725499],[-90.179921,38.632391],[-90.349706,38.374975],[-90.355183,38.216144],[-90.059428,38.013497],[-89.949889,37.88205],[-89.84035,37.903958],[-89.517211,37.690357],[-89.517211,37.537003],[-89.435057,37.34531],[-89.517211,37.279587],[-89.292656,36.994786],[-89.133825,36.983832],[-89.215979,36.578538],[-89.363857,36.622354],[-89.418626,36.496384],[-89.484349,36.496384],[-89.539119,36.496384],[-89.533642,36.249922],[-89.730812,35.997983],[-90.377091,35.997983],[-90.218259,36.184199],[-90.064905,36.304691],[-90.152536,36.496384],[-94.473842,36.501861],[-94.616242,36.501861],[-94.616242,37.000263],[-94.610765,39.158177],[-94.824366,39.20747],[-94.983197,39.442978],[-95.109167,39.541563],[-94.884612,39.831841],[-95.207752,39.908518],[-95.306337,40.001626],[-95.552799,40.264519],[-95.7664,40.587659],[-94.632673,40.571228],[-93.257961,40.582182],[-91.833957,40.609566]]]}}, +{"type":"Feature","id":"30","properties":{"name":"Montana","density":6.858},"geometry":{"type":"Polygon","coordinates":[[[-104.047534,49.000239],[-104.042057,47.861036],[-104.047534,45.944106],[-104.042057,44.996596],[-104.058488,44.996596],[-105.91517,45.002073],[-109.080842,45.002073],[-111.05254,45.002073],[-111.047063,44.476286],[-111.227803,44.580348],[-111.386634,44.75561],[-111.616665,44.547487],[-111.819312,44.509148],[-111.868605,44.563917],[-112.104113,44.520102],[-112.241036,44.569394],[-112.471068,44.481763],[-112.783254,44.48724],[-112.887315,44.394132],[-113.002331,44.448902],[-113.133778,44.772041],[-113.341901,44.782995],[-113.456917,44.865149],[-113.45144,45.056842],[-113.571933,45.128042],[-113.736241,45.330689],[-113.834826,45.522382],[-113.807441,45.604536],[-113.98818,45.703121],[-114.086765,45.593582],[-114.333228,45.456659],[-114.546828,45.560721],[-114.497536,45.670259],[-114.568736,45.774321],[-114.387997,45.88386],[-114.492059,46.037214],[-114.464674,46.272723],[-114.322274,46.645155],[-114.612552,46.639678],[-114.623506,46.705401],[-114.886399,46.809463],[-114.930214,46.919002],[-115.302646,47.187372],[-115.324554,47.258572],[-115.527201,47.302388],[-115.718894,47.42288],[-115.724371,47.696727],[-116.04751,47.976051],[-116.04751,49.000239],[-111.50165,48.994762],[-109.453274,49.000239],[-104.047534,49.000239]]]}}, +{"type":"Feature","id":"31","properties":{"name":"Nebraska","density":23.97},"geometry":{"type":"Polygon","coordinates":[[[-103.324578,43.002989],[-101.626726,42.997512],[-98.499393,42.997512],[-98.466531,42.94822],[-97.951699,42.767481],[-97.831206,42.866066],[-97.688806,42.844158],[-97.217789,42.844158],[-96.692003,42.657942],[-96.626279,42.515542],[-96.44554,42.488157],[-96.264801,42.039048],[-96.127878,41.973325],[-96.062155,41.798063],[-96.122401,41.67757],[-96.095016,41.540646],[-95.919754,41.453015],[-95.925231,41.201076],[-95.826646,40.976521],[-95.881416,40.719105],[-95.7664,40.587659],[-95.552799,40.264519],[-95.306337,40.001626],[-101.90605,40.001626],[-102.053927,40.001626],[-102.053927,41.003906],[-104.053011,41.003906],[-104.053011,43.002989],[-103.324578,43.002989]]]}}, +{"type":"Feature","id":"32","properties":{"name":"Nevada","density":24.80},"geometry":{"type":"Polygon","coordinates":[[[-117.027882,42.000709],[-114.04295,41.995232],[-114.048427,37.000263],[-114.048427,36.195153],[-114.152489,36.025367],[-114.251074,36.01989],[-114.371566,36.140383],[-114.738521,36.102045],[-114.678275,35.516012],[-114.596121,35.324319],[-114.574213,35.138103],[-114.634459,35.00118],[-115.85034,35.970598],[-116.540435,36.501861],[-117.498899,37.21934],[-118.71478,38.101128],[-120.001861,38.999346],[-119.996384,40.264519],[-120.001861,41.995232],[-118.698349,41.989755],[-117.027882,42.000709]]]}}, +{"type":"Feature","id":"33","properties":{"name":"New Hampshire","density":147},"geometry":{"type":"Polygon","coordinates":[[[-71.08183,45.303304],[-71.032537,44.657025],[-70.966814,43.34256],[-70.807983,43.227544],[-70.824413,43.128959],[-70.703921,43.057759],[-70.818936,42.871543],[-70.917521,42.887974],[-71.185891,42.789389],[-71.29543,42.696281],[-72.456542,42.729142],[-72.544173,42.80582],[-72.533219,42.953697],[-72.445588,43.008466],[-72.456542,43.150867],[-72.379864,43.572591],[-72.204602,43.769761],[-72.116971,43.994316],[-72.02934,44.07647],[-72.034817,44.322932],[-71.700724,44.41604],[-71.536416,44.585825],[-71.629524,44.750133],[-71.4926,44.914442],[-71.503554,45.013027],[-71.361154,45.270443],[-71.131122,45.243058],[-71.08183,45.303304]]]}}, +{"type":"Feature","id":"34","properties":{"name":"New Jersey","density":1189 },"geometry":{"type":"Polygon","coordinates":[[[-74.236547,41.14083],[-73.902454,40.998429],[-74.022947,40.708151],[-74.187255,40.642428],[-74.274886,40.489074],[-74.001039,40.412397],[-73.979131,40.297381],[-74.099624,39.760641],[-74.411809,39.360824],[-74.614456,39.245808],[-74.795195,38.993869],[-74.888303,39.158177],[-75.178581,39.240331],[-75.534582,39.459409],[-75.55649,39.607286],[-75.561967,39.629194],[-75.507197,39.683964],[-75.414089,39.804456],[-75.145719,39.88661],[-75.129289,39.963288],[-74.82258,40.127596],[-74.773287,40.215227],[-75.058088,40.417874],[-75.069042,40.543843],[-75.195012,40.576705],[-75.205966,40.691721],[-75.052611,40.866983],[-75.134765,40.971045],[-74.882826,41.179168],[-74.828057,41.288707],[-74.69661,41.359907],[-74.236547,41.14083]]]}}, +{"type":"Feature","id":"35","properties":{"name":"New Mexico","density":17.16},"geometry":{"type":"Polygon","coordinates":[[[-107.421329,37.000263],[-106.868158,36.994786],[-104.337812,36.994786],[-103.001438,37.000263],[-103.001438,36.501861],[-103.039777,36.501861],[-103.045254,34.01533],[-103.067161,33.002096],[-103.067161,31.999816],[-106.616219,31.999816],[-106.643603,31.901231],[-106.528588,31.786216],[-108.210008,31.786216],[-108.210008,31.331629],[-109.04798,31.331629],[-109.042503,37.000263],[-107.421329,37.000263]]]}}, +{"type":"Feature","id":"36","properties":{"name":"New York","density":412.3},"geometry":{"type":"Polygon","coordinates":[[[-73.343806,45.013027],[-73.332852,44.804903],[-73.387622,44.618687],[-73.294514,44.437948],[-73.321898,44.246255],[-73.436914,44.043608],[-73.349283,43.769761],[-73.404052,43.687607],[-73.245221,43.523299],[-73.278083,42.833204],[-73.267129,42.745573],[-73.508114,42.08834],[-73.486206,42.050002],[-73.55193,41.294184],[-73.48073,41.21203],[-73.727192,41.102491],[-73.655992,40.987475],[-73.22879,40.905321],[-73.141159,40.965568],[-72.774204,40.965568],[-72.587988,40.998429],[-72.28128,41.157261],[-72.259372,41.042245],[-72.100541,40.992952],[-72.467496,40.845075],[-73.239744,40.625997],[-73.562884,40.582182],[-73.776484,40.593136],[-73.935316,40.543843],[-74.022947,40.708151],[-73.902454,40.998429],[-74.236547,41.14083],[-74.69661,41.359907],[-74.740426,41.431108],[-74.89378,41.436584],[-75.074519,41.60637],[-75.052611,41.754247],[-75.173104,41.869263],[-75.249781,41.863786],[-75.35932,42.000709],[-79.76278,42.000709],[-79.76278,42.252649],[-79.76278,42.269079],[-79.149363,42.55388],[-79.050778,42.690804],[-78.853608,42.783912],[-78.930285,42.953697],[-79.012439,42.986559],[-79.072686,43.260406],[-78.486653,43.375421],[-77.966344,43.369944],[-77.75822,43.34256],[-77.533665,43.233021],[-77.391265,43.276836],[-76.958587,43.271359],[-76.695693,43.34256],[-76.41637,43.523299],[-76.235631,43.528776],[-76.230154,43.802623],[-76.137046,43.961454],[-76.3616,44.070993],[-76.312308,44.196962],[-75.912491,44.366748],[-75.764614,44.514625],[-75.282643,44.848718],[-74.828057,45.018503],[-74.148916,44.991119],[-73.343806,45.013027]]]}}, +{"type":"Feature","id":"37","properties":{"name":"North Carolina","density":198.2},"geometry":{"type":"Polygon","coordinates":[[[-80.978661,36.562108],[-80.294043,36.545677],[-79.510841,36.5402],[-75.868676,36.551154],[-75.75366,36.151337],[-76.032984,36.189676],[-76.071322,36.140383],[-76.410893,36.080137],[-76.460185,36.025367],[-76.68474,36.008937],[-76.673786,35.937736],[-76.399939,35.987029],[-76.3616,35.943213],[-76.060368,35.992506],[-75.961783,35.899398],[-75.781044,35.937736],[-75.715321,35.696751],[-75.775568,35.581735],[-75.89606,35.570781],[-76.147999,35.324319],[-76.482093,35.313365],[-76.536862,35.14358],[-76.394462,34.973795],[-76.279446,34.940933],[-76.493047,34.661609],[-76.673786,34.694471],[-76.991448,34.667086],[-77.210526,34.60684],[-77.555573,34.415147],[-77.82942,34.163208],[-77.971821,33.845545],[-78.179944,33.916745],[-78.541422,33.851022],[-79.675149,34.80401],[-80.797922,34.820441],[-80.781491,34.935456],[-80.934845,35.105241],[-81.038907,35.044995],[-81.044384,35.149057],[-82.276696,35.198349],[-82.550543,35.160011],[-82.764143,35.066903],[-83.109191,35.00118],[-83.618546,34.984749],[-84.319594,34.990226],[-84.29221,35.225734],[-84.09504,35.247642],[-84.018363,35.41195],[-83.7719,35.559827],[-83.498053,35.565304],[-83.251591,35.718659],[-82.994175,35.773428],[-82.775097,35.997983],[-82.638174,36.063706],[-82.610789,35.965121],[-82.216449,36.156814],[-82.03571,36.118475],[-81.909741,36.304691],[-81.723525,36.353984],[-81.679709,36.589492],[-80.978661,36.562108]]]}}, +{"type":"Feature","id":"38","properties":{"name":"North Dakota","density":9.916},"geometry":{"type":"Polygon","coordinates":[[[-97.228743,49.000239],[-97.097296,48.682577],[-97.16302,48.545653],[-97.130158,48.140359],[-97.053481,47.948667],[-96.856311,47.609096],[-96.823449,46.968294],[-96.785111,46.924479],[-96.801542,46.656109],[-96.719387,46.437031],[-96.598895,46.332969],[-96.560556,45.933153],[-104.047534,45.944106],[-104.042057,47.861036],[-104.047534,49.000239],[-97.228743,49.000239]]]}}, +{"type":"Feature","id":"39","properties":{"name":"Ohio","density":281.9},"geometry":{"type":"Polygon","coordinates":[[[-80.518598,41.978802],[-80.518598,40.636951],[-80.666475,40.582182],[-80.595275,40.472643],[-80.600752,40.319289],[-80.737675,40.078303],[-80.830783,39.711348],[-81.219646,39.388209],[-81.345616,39.344393],[-81.455155,39.410117],[-81.57017,39.267716],[-81.685186,39.273193],[-81.811156,39.0815],[-81.783771,38.966484],[-81.887833,38.873376],[-82.03571,39.026731],[-82.221926,38.785745],[-82.172634,38.632391],[-82.293127,38.577622],[-82.331465,38.446175],[-82.594358,38.424267],[-82.731282,38.561191],[-82.846298,38.588575],[-82.890113,38.758361],[-83.032514,38.725499],[-83.142052,38.626914],[-83.519961,38.703591],[-83.678792,38.632391],[-83.903347,38.769315],[-84.215533,38.807653],[-84.231963,38.895284],[-84.43461,39.103408],[-84.817996,39.103408],[-84.801565,40.500028],[-84.807042,41.694001],[-83.454238,41.732339],[-83.065375,41.595416],[-82.933929,41.513262],[-82.835344,41.589939],[-82.616266,41.431108],[-82.479343,41.381815],[-82.013803,41.513262],[-81.739956,41.485877],[-81.444201,41.672093],[-81.011523,41.852832],[-80.518598,41.978802],[-80.518598,41.978802]]]}}, +{"type":"Feature","id":"40","properties":{"name":"Oklahoma","density":55.22},"geometry":{"type":"Polygon","coordinates":[[[-100.087706,37.000263],[-94.616242,37.000263],[-94.616242,36.501861],[-94.430026,35.395519],[-94.484796,33.637421],[-94.868182,33.74696],[-94.966767,33.861976],[-95.224183,33.960561],[-95.289906,33.87293],[-95.547322,33.878407],[-95.602092,33.933176],[-95.8376,33.834591],[-95.936185,33.889361],[-96.149786,33.840068],[-96.346956,33.686714],[-96.423633,33.774345],[-96.631756,33.845545],[-96.850834,33.845545],[-96.922034,33.960561],[-97.173974,33.736006],[-97.256128,33.861976],[-97.371143,33.823637],[-97.458774,33.905791],[-97.694283,33.982469],[-97.869545,33.851022],[-97.946222,33.987946],[-98.088623,34.004376],[-98.170777,34.113915],[-98.36247,34.157731],[-98.488439,34.064623],[-98.570593,34.146777],[-98.767763,34.135823],[-98.986841,34.223454],[-99.189488,34.2125],[-99.260688,34.404193],[-99.57835,34.415147],[-99.698843,34.382285],[-99.923398,34.573978],[-100.000075,34.563024],[-100.000075,36.501861],[-101.812942,36.501861],[-103.001438,36.501861],[-103.001438,37.000263],[-102.042974,36.994786],[-100.087706,37.000263]]]}}, +{"type":"Feature","id":"41","properties":{"name":"Oregon","density":40.33},"geometry":{"type":"Polygon","coordinates":[[[-123.211348,46.174138],[-123.11824,46.185092],[-122.904639,46.08103],[-122.811531,45.960537],[-122.762239,45.659305],[-122.247407,45.549767],[-121.809251,45.708598],[-121.535404,45.725029],[-121.217742,45.670259],[-121.18488,45.604536],[-120.637186,45.746937],[-120.505739,45.697644],[-120.209985,45.725029],[-119.963522,45.823614],[-119.525367,45.911245],[-119.125551,45.933153],[-118.988627,45.998876],[-116.918344,45.993399],[-116.78142,45.823614],[-116.545912,45.752413],[-116.463758,45.61549],[-116.671881,45.319735],[-116.732128,45.144473],[-116.847143,45.02398],[-116.830713,44.930872],[-116.934774,44.782995],[-117.038836,44.750133],[-117.241483,44.394132],[-117.170283,44.257209],[-116.97859,44.240778],[-116.896436,44.158624],[-117.027882,43.830007],[-117.027882,42.000709],[-118.698349,41.989755],[-120.001861,41.995232],[-121.037003,41.995232],[-122.378853,42.011663],[-123.233256,42.006186],[-124.213628,42.000709],[-124.356029,42.115725],[-124.432706,42.438865],[-124.416275,42.663419],[-124.553198,42.838681],[-124.454613,43.002989],[-124.383413,43.271359],[-124.235536,43.55616],[-124.169813,43.8081],[-124.060274,44.657025],[-124.076705,44.772041],[-123.97812,45.144473],[-123.939781,45.659305],[-123.994551,45.944106],[-123.945258,46.113892],[-123.545441,46.261769],[-123.370179,46.146753],[-123.211348,46.174138]]]}}, +{"type":"Feature","id":"42","properties":{"name":"Pennsylvania","density":284.3},"geometry":{"type":"Polygon","coordinates":[[[-79.76278,42.252649],[-79.76278,42.000709],[-75.35932,42.000709],[-75.249781,41.863786],[-75.173104,41.869263],[-75.052611,41.754247],[-75.074519,41.60637],[-74.89378,41.436584],[-74.740426,41.431108],[-74.69661,41.359907],[-74.828057,41.288707],[-74.882826,41.179168],[-75.134765,40.971045],[-75.052611,40.866983],[-75.205966,40.691721],[-75.195012,40.576705],[-75.069042,40.543843],[-75.058088,40.417874],[-74.773287,40.215227],[-74.82258,40.127596],[-75.129289,39.963288],[-75.145719,39.88661],[-75.414089,39.804456],[-75.616736,39.831841],[-75.786521,39.722302],[-79.477979,39.722302],[-80.518598,39.722302],[-80.518598,40.636951],[-80.518598,41.978802],[-80.518598,41.978802],[-80.332382,42.033571],[-79.76278,42.269079],[-79.76278,42.252649]]]}}, +{"type":"Feature","id":"44","properties":{"name":"Rhode Island","density":1006 },"geometry":{"type":"MultiPolygon","coordinates":[[[[-71.196845,41.67757],[-71.120168,41.496831],[-71.317338,41.474923],[-71.196845,41.67757]]],[[[-71.530939,42.01714],[-71.383061,42.01714],[-71.328292,41.781632],[-71.22423,41.710431],[-71.344723,41.726862],[-71.448785,41.578985],[-71.481646,41.370861],[-71.859555,41.321569],[-71.799309,41.414677],[-71.799309,42.006186],[-71.530939,42.01714]]]]}}, +{"type":"Feature","id":"45","properties":{"name":"South Carolina","density":155.4},"geometry":{"type":"Polygon","coordinates":[[[-82.764143,35.066903],[-82.550543,35.160011],[-82.276696,35.198349],[-81.044384,35.149057],[-81.038907,35.044995],[-80.934845,35.105241],[-80.781491,34.935456],[-80.797922,34.820441],[-79.675149,34.80401],[-78.541422,33.851022],[-78.716684,33.80173],[-78.935762,33.637421],[-79.149363,33.380005],[-79.187701,33.171881],[-79.357487,33.007573],[-79.582041,33.007573],[-79.631334,32.887081],[-79.866842,32.755634],[-79.998289,32.613234],[-80.206412,32.552987],[-80.430967,32.399633],[-80.452875,32.328433],[-80.660998,32.246279],[-80.885553,32.032678],[-81.115584,32.120309],[-81.121061,32.290094],[-81.279893,32.558464],[-81.416816,32.629664],[-81.42777,32.843265],[-81.493493,33.007573],[-81.761863,33.160928],[-81.937125,33.347144],[-81.926172,33.462159],[-82.194542,33.631944],[-82.325988,33.81816],[-82.55602,33.94413],[-82.714851,34.152254],[-82.747713,34.26727],[-82.901067,34.486347],[-83.005129,34.469916],[-83.339222,34.683517],[-83.322791,34.787579],[-83.109191,35.00118],[-82.764143,35.066903]]]}}, +{"type":"Feature","id":"46","properties":{"name":"South Dakota","density":98.07},"geometry":{"type":"Polygon","coordinates":[[[-104.047534,45.944106],[-96.560556,45.933153],[-96.582464,45.818137],[-96.856311,45.604536],[-96.681049,45.412843],[-96.451017,45.297827],[-96.451017,43.501391],[-96.582464,43.479483],[-96.527695,43.397329],[-96.560556,43.222067],[-96.434587,43.123482],[-96.511264,43.052282],[-96.544125,42.855112],[-96.631756,42.707235],[-96.44554,42.488157],[-96.626279,42.515542],[-96.692003,42.657942],[-97.217789,42.844158],[-97.688806,42.844158],[-97.831206,42.866066],[-97.951699,42.767481],[-98.466531,42.94822],[-98.499393,42.997512],[-101.626726,42.997512],[-103.324578,43.002989],[-104.053011,43.002989],[-104.058488,44.996596],[-104.042057,44.996596],[-104.047534,45.944106]]]}}, +{"type":"Feature","id":"47","properties":{"name":"Tennessee","density":88.08},"geometry":{"type":"Polygon","coordinates":[[[-88.054868,36.496384],[-88.071299,36.677123],[-87.852221,36.633308],[-86.592525,36.655216],[-85.486183,36.616877],[-85.289013,36.627831],[-84.544149,36.594969],[-83.689746,36.584015],[-83.673316,36.600446],[-81.679709,36.589492],[-81.723525,36.353984],[-81.909741,36.304691],[-82.03571,36.118475],[-82.216449,36.156814],[-82.610789,35.965121],[-82.638174,36.063706],[-82.775097,35.997983],[-82.994175,35.773428],[-83.251591,35.718659],[-83.498053,35.565304],[-83.7719,35.559827],[-84.018363,35.41195],[-84.09504,35.247642],[-84.29221,35.225734],[-84.319594,34.990226],[-85.606675,34.984749],[-87.359296,35.00118],[-88.202745,34.995703],[-88.471115,34.995703],[-90.311367,34.995703],[-90.212782,35.023087],[-90.114197,35.198349],[-90.130628,35.439335],[-89.944412,35.603643],[-89.911551,35.756997],[-89.763673,35.811767],[-89.730812,35.997983],[-89.533642,36.249922],[-89.539119,36.496384],[-89.484349,36.496384],[-89.418626,36.496384],[-89.298133,36.507338],[-88.054868,36.496384]]]}}, +{"type":"Feature","id":"48","properties":{"name":"Texas","density":98.07},"geometry":{"type":"Polygon","coordinates":[[[-101.812942,36.501861],[-100.000075,36.501861],[-100.000075,34.563024],[-99.923398,34.573978],[-99.698843,34.382285],[-99.57835,34.415147],[-99.260688,34.404193],[-99.189488,34.2125],[-98.986841,34.223454],[-98.767763,34.135823],[-98.570593,34.146777],[-98.488439,34.064623],[-98.36247,34.157731],[-98.170777,34.113915],[-98.088623,34.004376],[-97.946222,33.987946],[-97.869545,33.851022],[-97.694283,33.982469],[-97.458774,33.905791],[-97.371143,33.823637],[-97.256128,33.861976],[-97.173974,33.736006],[-96.922034,33.960561],[-96.850834,33.845545],[-96.631756,33.845545],[-96.423633,33.774345],[-96.346956,33.686714],[-96.149786,33.840068],[-95.936185,33.889361],[-95.8376,33.834591],[-95.602092,33.933176],[-95.547322,33.878407],[-95.289906,33.87293],[-95.224183,33.960561],[-94.966767,33.861976],[-94.868182,33.74696],[-94.484796,33.637421],[-94.380734,33.544313],[-94.183564,33.593606],[-94.041164,33.54979],[-94.041164,33.018527],[-94.041164,31.994339],[-93.822086,31.775262],[-93.816609,31.556184],[-93.542762,31.15089],[-93.526331,30.93729],[-93.630393,30.679874],[-93.728978,30.575812],[-93.696116,30.438888],[-93.767317,30.334826],[-93.690639,30.143133],[-93.926148,29.787132],[-93.838517,29.688547],[-94.002825,29.68307],[-94.523134,29.546147],[-94.70935,29.622824],[-94.742212,29.787132],[-94.873659,29.672117],[-94.966767,29.699501],[-95.016059,29.557101],[-94.911997,29.496854],[-94.895566,29.310638],[-95.081782,29.113469],[-95.383014,28.867006],[-95.985477,28.604113],[-96.045724,28.647929],[-96.226463,28.582205],[-96.23194,28.642452],[-96.478402,28.598636],[-96.593418,28.724606],[-96.664618,28.697221],[-96.401725,28.439805],[-96.593418,28.357651],[-96.774157,28.406943],[-96.801542,28.226204],[-97.026096,28.039988],[-97.256128,27.694941],[-97.404005,27.333463],[-97.513544,27.360848],[-97.540929,27.229401],[-97.425913,27.262263],[-97.480682,26.99937],[-97.557359,26.988416],[-97.562836,26.840538],[-97.469728,26.758384],[-97.442344,26.457153],[-97.332805,26.353091],[-97.30542,26.161398],[-97.217789,25.991613],[-97.524498,25.887551],[-97.650467,26.018997],[-97.885976,26.06829],[-98.198161,26.057336],[-98.466531,26.221644],[-98.669178,26.238075],[-98.822533,26.369522],[-99.030656,26.413337],[-99.173057,26.539307],[-99.266165,26.840538],[-99.446904,27.021277],[-99.424996,27.174632],[-99.50715,27.33894],[-99.479765,27.48134],[-99.605735,27.640172],[-99.709797,27.656603],[-99.879582,27.799003],[-99.934351,27.979742],[-100.082229,28.14405],[-100.29583,28.280974],[-100.399891,28.582205],[-100.498476,28.66436],[-100.629923,28.905345],[-100.673738,29.102515],[-100.799708,29.244915],[-101.013309,29.370885],[-101.062601,29.458516],[-101.259771,29.535193],[-101.413125,29.754271],[-101.851281,29.803563],[-102.114174,29.792609],[-102.338728,29.869286],[-102.388021,29.765225],[-102.629006,29.732363],[-102.809745,29.524239],[-102.919284,29.190146],[-102.97953,29.184669],[-103.116454,28.987499],[-103.280762,28.982022],[-103.527224,29.135376],[-104.146119,29.381839],[-104.266611,29.513285],[-104.507597,29.639255],[-104.677382,29.924056],[-104.688336,30.181472],[-104.858121,30.389596],[-104.896459,30.570335],[-105.005998,30.685351],[-105.394861,30.855136],[-105.602985,31.085167],[-105.77277,31.167321],[-105.953509,31.364491],[-106.205448,31.468553],[-106.38071,31.731446],[-106.528588,31.786216],[-106.643603,31.901231],[-106.616219,31.999816],[-103.067161,31.999816],[-103.067161,33.002096],[-103.045254,34.01533],[-103.039777,36.501861],[-103.001438,36.501861],[-101.812942,36.501861]]]}}, +{"type":"Feature","id":"49","properties":{"name":"Utah","density":34.30},"geometry":{"type":"Polygon","coordinates":[[[-112.164359,41.995232],[-111.047063,42.000709],[-111.047063,40.998429],[-109.04798,40.998429],[-109.053457,39.125316],[-109.058934,38.27639],[-109.042503,38.166851],[-109.042503,37.000263],[-110.499369,37.00574],[-114.048427,37.000263],[-114.04295,41.995232],[-112.164359,41.995232]]]}}, +{"type":"Feature","id":"50","properties":{"name":"Vermont","density":67.73},"geometry":{"type":"Polygon","coordinates":[[[-71.503554,45.013027],[-71.4926,44.914442],[-71.629524,44.750133],[-71.536416,44.585825],[-71.700724,44.41604],[-72.034817,44.322932],[-72.02934,44.07647],[-72.116971,43.994316],[-72.204602,43.769761],[-72.379864,43.572591],[-72.456542,43.150867],[-72.445588,43.008466],[-72.533219,42.953697],[-72.544173,42.80582],[-72.456542,42.729142],[-73.267129,42.745573],[-73.278083,42.833204],[-73.245221,43.523299],[-73.404052,43.687607],[-73.349283,43.769761],[-73.436914,44.043608],[-73.321898,44.246255],[-73.294514,44.437948],[-73.387622,44.618687],[-73.332852,44.804903],[-73.343806,45.013027],[-72.308664,45.002073],[-71.503554,45.013027]]]}}, +{"type":"Feature","id":"51","properties":{"name":"Virginia","density":204.5},"geometry":{"type":"MultiPolygon","coordinates":[[[[-75.397659,38.013497],[-75.244304,38.029928],[-75.375751,37.860142],[-75.512674,37.799896],[-75.594828,37.569865],[-75.802952,37.197433],[-75.972737,37.120755],[-76.027507,37.257679],[-75.939876,37.564388],[-75.671506,37.95325],[-75.397659,38.013497]]],[[[-76.016553,37.95325],[-75.994645,37.95325],[-76.043938,37.95325],[-76.016553,37.95325]]],[[[-78.349729,39.464886],[-77.82942,39.130793],[-77.719881,39.322485],[-77.566527,39.306055],[-77.456988,39.223901],[-77.456988,39.076023],[-77.248864,39.026731],[-77.117418,38.933623],[-77.040741,38.791222],[-77.128372,38.632391],[-77.248864,38.588575],[-77.325542,38.446175],[-77.281726,38.342113],[-77.013356,38.374975],[-76.964064,38.216144],[-76.613539,38.15042],[-76.514954,38.024451],[-76.235631,37.887527],[-76.3616,37.608203],[-76.246584,37.389126],[-76.383508,37.285064],[-76.399939,37.159094],[-76.273969,37.082417],[-76.410893,36.961924],[-76.619016,37.120755],[-76.668309,37.065986],[-76.48757,36.95097],[-75.994645,36.923586],[-75.868676,36.551154],[-79.510841,36.5402],[-80.294043,36.545677],[-80.978661,36.562108],[-81.679709,36.589492],[-83.673316,36.600446],[-83.136575,36.742847],[-83.070852,36.852385],[-82.879159,36.890724],[-82.868205,36.978355],[-82.720328,37.044078],[-82.720328,37.120755],[-82.353373,37.268633],[-81.969987,37.537003],[-81.986418,37.454849],[-81.849494,37.285064],[-81.679709,37.20291],[-81.55374,37.208387],[-81.362047,37.339833],[-81.225123,37.235771],[-80.967707,37.290541],[-80.513121,37.482234],[-80.474782,37.421987],[-80.29952,37.509618],[-80.294043,37.690357],[-80.184505,37.849189],[-79.998289,37.997066],[-79.921611,38.177805],[-79.724442,38.364021],[-79.647764,38.594052],[-79.477979,38.457129],[-79.313671,38.413313],[-79.209609,38.495467],[-78.996008,38.851469],[-78.870039,38.763838],[-78.404499,39.169131],[-78.349729,39.464886]]]]}}, +{"type":"Feature","id":"53","properties":{"name":"Washington","density":102.6},"geometry":{"type":"MultiPolygon","coordinates":[[[[-117.033359,49.000239],[-117.044313,47.762451],[-117.038836,46.426077],[-117.055267,46.343923],[-116.92382,46.168661],[-116.918344,45.993399],[-118.988627,45.998876],[-119.125551,45.933153],[-119.525367,45.911245],[-119.963522,45.823614],[-120.209985,45.725029],[-120.505739,45.697644],[-120.637186,45.746937],[-121.18488,45.604536],[-121.217742,45.670259],[-121.535404,45.725029],[-121.809251,45.708598],[-122.247407,45.549767],[-122.762239,45.659305],[-122.811531,45.960537],[-122.904639,46.08103],[-123.11824,46.185092],[-123.211348,46.174138],[-123.370179,46.146753],[-123.545441,46.261769],[-123.72618,46.300108],[-123.874058,46.239861],[-124.065751,46.327492],[-124.027412,46.464416],[-123.895966,46.535616],[-124.098612,46.74374],[-124.235536,47.285957],[-124.31769,47.357157],[-124.427229,47.740543],[-124.624399,47.88842],[-124.706553,48.184175],[-124.597014,48.381345],[-124.394367,48.288237],[-123.983597,48.162267],[-123.704273,48.167744],[-123.424949,48.118452],[-123.162056,48.167744],[-123.036086,48.080113],[-122.800578,48.08559],[-122.636269,47.866512],[-122.515777,47.882943],[-122.493869,47.587189],[-122.422669,47.318818],[-122.324084,47.346203],[-122.422669,47.576235],[-122.395284,47.800789],[-122.230976,48.030821],[-122.362422,48.123929],[-122.373376,48.288237],[-122.471961,48.468976],[-122.422669,48.600422],[-122.488392,48.753777],[-122.647223,48.775685],[-122.795101,48.8907],[-122.756762,49.000239],[-117.033359,49.000239]]],[[[-122.718423,48.310145],[-122.586977,48.35396],[-122.608885,48.151313],[-122.767716,48.227991],[-122.718423,48.310145]]],[[[-123.025132,48.583992],[-122.915593,48.715438],[-122.767716,48.556607],[-122.811531,48.419683],[-123.041563,48.458022],[-123.025132,48.583992]]]]}}, +{"type":"Feature","id":"54","properties":{"name":"West Virginia","density":77.06},"geometry":{"type":"Polygon","coordinates":[[[-80.518598,40.636951],[-80.518598,39.722302],[-79.477979,39.722302],[-79.488933,39.20747],[-79.291763,39.300578],[-79.094593,39.470363],[-78.963147,39.437501],[-78.765977,39.585379],[-78.470222,39.514178],[-78.431884,39.623717],[-78.267575,39.61824],[-78.174467,39.694917],[-78.004682,39.601809],[-77.834897,39.601809],[-77.719881,39.322485],[-77.82942,39.130793],[-78.349729,39.464886],[-78.404499,39.169131],[-78.870039,38.763838],[-78.996008,38.851469],[-79.209609,38.495467],[-79.313671,38.413313],[-79.477979,38.457129],[-79.647764,38.594052],[-79.724442,38.364021],[-79.921611,38.177805],[-79.998289,37.997066],[-80.184505,37.849189],[-80.294043,37.690357],[-80.29952,37.509618],[-80.474782,37.421987],[-80.513121,37.482234],[-80.967707,37.290541],[-81.225123,37.235771],[-81.362047,37.339833],[-81.55374,37.208387],[-81.679709,37.20291],[-81.849494,37.285064],[-81.986418,37.454849],[-81.969987,37.537003],[-82.101434,37.553434],[-82.293127,37.668449],[-82.342419,37.783465],[-82.50125,37.931343],[-82.621743,38.123036],[-82.594358,38.424267],[-82.331465,38.446175],[-82.293127,38.577622],[-82.172634,38.632391],[-82.221926,38.785745],[-82.03571,39.026731],[-81.887833,38.873376],[-81.783771,38.966484],[-81.811156,39.0815],[-81.685186,39.273193],[-81.57017,39.267716],[-81.455155,39.410117],[-81.345616,39.344393],[-81.219646,39.388209],[-80.830783,39.711348],[-80.737675,40.078303],[-80.600752,40.319289],[-80.595275,40.472643],[-80.666475,40.582182],[-80.518598,40.636951]]]}}, +{"type":"Feature","id":"55","properties":{"name":"Wisconsin","density":105.2},"geometry":{"type":"Polygon","coordinates":[[[-90.415429,46.568478],[-90.229213,46.508231],[-90.119674,46.338446],[-89.09001,46.135799],[-88.662808,45.987922],[-88.531362,46.020784],[-88.10416,45.922199],[-87.989145,45.796229],[-87.781021,45.675736],[-87.791975,45.500474],[-87.885083,45.363551],[-87.649574,45.341643],[-87.742682,45.199243],[-87.589328,45.095181],[-87.627666,44.974688],[-87.819359,44.95278],[-87.983668,44.722749],[-88.043914,44.563917],[-87.928898,44.536533],[-87.775544,44.640595],[-87.611236,44.837764],[-87.403112,44.914442],[-87.238804,45.166381],[-87.03068,45.22115],[-87.047111,45.089704],[-87.189511,44.969211],[-87.468835,44.552964],[-87.545512,44.322932],[-87.540035,44.158624],[-87.644097,44.103854],[-87.737205,43.8793],[-87.704344,43.687607],[-87.791975,43.561637],[-87.912467,43.249452],[-87.885083,43.002989],[-87.76459,42.783912],[-87.802929,42.493634],[-88.788778,42.493634],[-90.639984,42.510065],[-90.711184,42.636034],[-91.067185,42.75105],[-91.143862,42.909881],[-91.176724,43.134436],[-91.056231,43.254929],[-91.204109,43.353514],[-91.215062,43.501391],[-91.269832,43.616407],[-91.242447,43.775238],[-91.43414,43.994316],[-91.592971,44.032654],[-91.877772,44.202439],[-91.927065,44.333886],[-92.233773,44.443425],[-92.337835,44.552964],[-92.545959,44.569394],[-92.808852,44.750133],[-92.737652,45.117088],[-92.75956,45.286874],[-92.644544,45.440228],[-92.770513,45.566198],[-92.885529,45.577151],[-92.869098,45.719552],[-92.639067,45.933153],[-92.354266,46.015307],[-92.29402,46.075553],[-92.29402,46.667063],[-92.091373,46.749217],[-92.014696,46.705401],[-91.790141,46.694447],[-91.09457,46.864232],[-90.837154,46.95734],[-90.749522,46.88614],[-90.886446,46.754694],[-90.55783,46.584908],[-90.415429,46.568478]]]}}, +{"type":"Feature","id":"56","properties":{"name":"Wyoming","density":5.851},"geometry":{"type":"Polygon","coordinates":[[[-109.080842,45.002073],[-105.91517,45.002073],[-104.058488,44.996596],[-104.053011,43.002989],[-104.053011,41.003906],[-105.728954,40.998429],[-107.919731,41.003906],[-109.04798,40.998429],[-111.047063,40.998429],[-111.047063,42.000709],[-111.047063,44.476286],[-111.05254,45.002073],[-109.080842,45.002073]]]}}, +{"type":"Feature","id":"72","properties":{"name":"Puerto Rico","density":1082 },"geometry":{"type":"Polygon","coordinates":[[[-66.448338,17.984326],[-66.771478,18.006234],[-66.924832,17.929556],[-66.985078,17.973372],[-67.209633,17.956941],[-67.154863,18.19245],[-67.269879,18.362235],[-67.094617,18.515589],[-66.957694,18.488204],[-66.409999,18.488204],[-65.840398,18.433435],[-65.632274,18.367712],[-65.626797,18.203403],[-65.730859,18.186973],[-65.834921,18.017187],[-66.234737,17.929556],[-66.448338,17.984326]]]}} +]} diff --git a/examples/demos/basemap/amap-data.ts b/examples/demos/basemap/amap-data.ts new file mode 100644 index 00000000000..a4c169361fe --- /dev/null +++ b/examples/demos/basemap/amap-data.ts @@ -0,0 +1,45 @@ +import { LineLayer, Source } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const amapData: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [121.434765, 31.256735], + zoom: 14.83, + maxZoom: 25, + }, + }); + + const geoData = { + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + properties: {}, + geometry: { + type: 'LineString', + coordinates: [ + [120.104021, 30.262493], + [120.103875, 30.262601], + [120.103963, 30.262694], + ], + }, + }, + ], + }; + + const source = new Source(geoData); + const layer = new LineLayer({ blend: 'normal', autoFit: true }) + .source(source) + .size(2) + .shape('line') + .color('#f00') + .style({ + opacity: 1, + }); + scene.addLayer(layer); + + return scene; +}; diff --git a/examples/demos/basemap/index.ts b/examples/demos/basemap/index.ts new file mode 100644 index 00000000000..7995266bd78 --- /dev/null +++ b/examples/demos/basemap/index.ts @@ -0,0 +1,2 @@ +export { amapData } from './amap-data'; +export { wgs84Data } from './wgs84-data'; diff --git a/examples/demos/basemap/wgs84-data.ts b/examples/demos/basemap/wgs84-data.ts new file mode 100644 index 00000000000..0c6341cb3e3 --- /dev/null +++ b/examples/demos/basemap/wgs84-data.ts @@ -0,0 +1,70 @@ +import { LineLayer, Source } from '@antv/l7'; +import type { Map } from 'maplibre-gl'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const wgs84Data: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [121.434765, 31.256735], + zoom: 14.83, + maxZoom: 23.9, + }, + }); + + const geoData = { + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + properties: {}, + geometry: { + type: 'LineString', + coordinates: [ + [120.10121458655186, 30.269329295915544], + [120.10122467185921, 30.2693341645727], + [120.10123176240315, 30.269323019911795], + ], + }, + }, + ], + }; + + const source = new Source(geoData); + const layer = new LineLayer({ blend: 'normal', autoFit: true }) + .source(source) + .size(2) + .shape('line') + .color('#f00') + .style({ + opacity: 1, + }); + + scene.addLayer(layer); + + if (scene.getType() === 'mapbox') { + const baseMap = scene.map as Map; + baseMap.on('load', () => { + baseMap.addSource('route', { + type: 'geojson', + data: geoData, + }); + baseMap.addLayer({ + id: 'route', + type: 'line', + source: 'route', + layout: { + 'line-join': 'round', + 'line-cap': 'round', + }, + paint: { + 'line-color': '#0083FE', + 'line-width': 2, + }, + }); + }); + } + + return scene; +}; diff --git a/examples/demos/bugfix/color.ts b/examples/demos/bugfix/color.ts deleted file mode 100644 index 8446ea419e9..00000000000 --- a/examples/demos/bugfix/color.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { LineLayer, PolygonLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; - -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', - center: [-96, 37.8], - zoom: 3, - }), - }); - scene.on('loaded', () => { - fetch( - // 'https://gw.alipayobjects.com/os/basement_prod/d36ad90e-3902-4742-b8a2-d93f7e5dafa2.json' - 'https://mdn.alipayobjects.com/afts/file/A*CFbnRqXpg8wAAAAAAAAAAAAADrd2AQ/test.json', - ) - .then((res) => res.json()) - .then((data) => { - console.log(data); - const layer = new PolygonLayer({ autoFit: true }) - .source(data) - .color('#f00') - .shape('fill') - .active(true); - const layer2 = new LineLayer({ - zIndex: 2, - }) - .source(data) - .color('#ffffff') - .active(true) - .size(1) - .style({ - lineType: 'dash', - dashArray: [2, 2], - }); - scene.addLayer(layer); - scene.addLayer(layer2); - - setTimeout(() => { - layer.color('#f0f'); - layer2.color('#00f'); - scene.render(); - }, 1000); - }); - }); -} diff --git a/examples/demos/bugfix/data-shake.ts b/examples/demos/bugfix/data-shake.ts new file mode 100644 index 00000000000..126e4092c61 --- /dev/null +++ b/examples/demos/bugfix/data-shake.ts @@ -0,0 +1,86 @@ +import { PointLayer } from '@antv/l7'; +import { featureEach, interpolate, randomPoint } from '@turf/turf'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +const points = randomPoint(30, { bbox: [120.103217, 30.26128, 120.10348, 30.261506] }); + +featureEach(points, function (point) { + // add a random property to each point + point.properties.solRad = Math.random() * 50; +}); + +const GEO_DATA = interpolate(points, 0.001, { + gridType: 'point', + property: 'solRad', + units: 'miles', +}); + +export const dataShake: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [120.10321541789858, 30.261273569440405], + zoom: 21.588541277244076, + maxZoom: 23, + }, + }); + + const layer = new PointLayer({ autoFit: false }) + .source(GEO_DATA) + .size(15) + .color('rgb(255, 0, 0)') + .shape('circle') + .style({ + stroke: '#0083FE', + strokeWidth: 2, + // unit: 'meter', + }); + + scene.addLayer(layer); + // scene.setZoomAndCenter(22, [120.10348, 30.261506]); + + const mapType = scene.getType(); + + if (['default', 'mapbox'].includes(mapType)) { + const isMapbox = mapType === 'mapbox'; + + dataShake.extendGUI = (gui) => { + return [ + gui.add( + { + dispatchWheelEvt: () => { + const dom = document.querySelector( + isMapbox ? '.l7-marker-container' : '.l7-canvas-container', + ); + // console.log('dom: ', dom); + const wheelEvt = new WheelEvent('wheel', { + bubbles: true, + cancelable: true, + composed: true, + clientX: 1329, + clientY: 168, + deltaY: 200, + }); + // console.log('wheelEvt: ', wheelEvt); + dom?.dispatchEvent(wheelEvt); + + const wheelEvt2 = new WheelEvent('wheel', { + bubbles: true, + cancelable: true, + composed: true, + clientX: 1329, + clientY: 168, + deltaY: 400, + }); + dom?.dispatchEvent(wheelEvt2); + }, + }, + 'dispatchWheelEvt', + ), + ]; + }; + } + + return scene; +}; diff --git a/examples/demos/bugfix/event_legend.ts b/examples/demos/bugfix/event_legend.ts deleted file mode 100644 index 668959c8895..00000000000 --- a/examples/demos/bugfix/event_legend.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { PolygonLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; -import { sleep } from '../../utils/sleep'; - -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', - center: [116.368652, 39.93866], - zoom: 10.07, - }), - }); - scene.on('loaded', () => { - fetch('https://gw.alipayobjects.com/os/basement_prod/1d27c363-af3a-469e-ab5b-7a7e1ce4f311.json') - .then((res) => res.json()) - .then((data) => { - const layer = new PolygonLayer({ - autoFit: true, - }) - .source(data) - .color( - 'unit_price', - [ - '#1A4397', - '#2555B7', - '#3165D1', - '#467BE8', - '#6296FE', - '#7EA6F9', - '#98B7F7', - '#BDD0F8', - '#DDE6F7', - '#F2F5FC', - ].reverse(), - ) - .shape('fill') - .active(true); - - scene.addLayer(layer); - - layer.on('legend:color', (color) => { - console.log('color legend', layer.getLegend('color')); - }); - - sleep(2000) - .then(() => { - console.log('update data'); - const newData = { - ...data, - features: data.features.slice(1, 10), - }; - layer.setData(newData); - }) - .then(() => sleep(2000)) - .then(() => { - console.log('update color'); - layer.color('unit_price', [ - '#1A4397', - '#2555B7', - '#3165D1', - '#467BE8', - '#6296FE', - '#7EA6F9', - '#98B7F7', - '#BDD0F8', - '#DDE6F7', - '#F2F5FC', - ]); - scene.render(); - }); - }); - }); -} diff --git a/examples/demos/bugfix/index.ts b/examples/demos/bugfix/index.ts index 7bd86c1f3ad..29764c932b0 100644 --- a/examples/demos/bugfix/index.ts +++ b/examples/demos/bugfix/index.ts @@ -1,8 +1,10 @@ -export { MapRender as color } from './color'; -export { MapRender as event_legend } from './event_legend'; -export { MapRender as remove_muti_layer } from './remove-muti-layer'; -export { MapRender as setData } from './set-data'; -export { MapRender as size } from './size'; -export { MapRender as text } from './text_offsets'; -export { MapRender as tile_update } from './tile_update'; -export { MapRender as touchend } from './touchend'; +export { dataShake } from './data-shake'; +export { legendEvent } from './legend-event'; +export { mutiPolygon } from './muti-polygon'; +export { removeMutiLayer } from './remove-muti-layer'; +export { setColor } from './set-color'; +export { setData } from './set-data'; +export { setSize } from './set-size'; +export { textOffsets } from './text-offsets'; +export { tileUpdate } from './tile-update'; +export { touchEvent } from './touch-event'; diff --git a/examples/demos/bugfix/legend-event.ts b/examples/demos/bugfix/legend-event.ts new file mode 100644 index 00000000000..fc0afca7c0b --- /dev/null +++ b/examples/demos/bugfix/legend-event.ts @@ -0,0 +1,86 @@ +import { PolygonLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const legendEvent: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [116.368652, 39.93866], + zoom: 10.07, + }, + }); + + const data = await fetch( + 'https://gw.alipayobjects.com/os/basement_prod/1d27c363-af3a-469e-ab5b-7a7e1ce4f311.json', + ).then((res) => res.json()); + + const layer = new PolygonLayer({ + autoFit: true, + }) + .source(data) + .color( + 'unit_price', + [ + '#1A4397', + '#2555B7', + '#3165D1', + '#467BE8', + '#6296FE', + '#7EA6F9', + '#98B7F7', + '#BDD0F8', + '#DDE6F7', + '#F2F5FC', + ].reverse(), + ) + .shape('fill') + .active(true); + + scene.addLayer(layer); + + layer.on('legend:color', (color) => { + console.log('color legend', layer.getLegend('color')); + }); + + legendEvent.extendGUI = (gui) => { + return [ + gui.add( + { + setData: () => { + console.log('update data'); + const newData = { + ...data, + features: data.features.slice(1, 10), + }; + layer.setData(newData); + }, + }, + 'setData', + ), + gui.add( + { + updateColor: () => { + console.log('update color'); + layer.color('unit_price', [ + '#1A4397', + '#2555B7', + '#3165D1', + '#467BE8', + '#6296FE', + '#7EA6F9', + '#98B7F7', + '#BDD0F8', + '#DDE6F7', + '#F2F5FC', + ]); + scene.render(); + }, + }, + 'updateColor', + ), + ]; + }; + + return scene; +}; diff --git a/examples/demos/bugfix/muti-polygon.ts b/examples/demos/bugfix/muti-polygon.ts new file mode 100644 index 00000000000..cc07259bf5e --- /dev/null +++ b/examples/demos/bugfix/muti-polygon.ts @@ -0,0 +1,41 @@ +import { PolygonLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const mutiPolygon: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [121.434765, 31.256735], + zoom: 14.83, + }, + }); + + const geoData = await fetch( + 'https://npm.elemecdn.com/static-geo-atlas/geo-data/choropleth-data/country/100000_country_province.json', + ) + .then((res) => res.json()) + .then((data) => data.features.slice(4, 5)); + + const layer = new PolygonLayer({ + autoFit: true, + }) + .source(geoData, { + parser: { + type: 'json', + geometry: 'geometry', + }, + }) + .color('rgb(22,199,255)') + .shape('fill') + // .shape('extrude') + // .size(1200 * 100) + .active(true) + .style({ + opacity: 0.5, + }); + + scene.addLayer(layer); + + return scene; +}; diff --git a/examples/demos/bugfix/remove-muti-layer.ts b/examples/demos/bugfix/remove-muti-layer.ts index b2950d5e548..e353f3bf82f 100644 --- a/examples/demos/bugfix/remove-muti-layer.ts +++ b/examples/demos/bugfix/remove-muti-layer.ts @@ -1,6 +1,6 @@ -import { PolygonLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { PolygonLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; const data1 = { type: 'FeatureCollection', @@ -271,49 +271,57 @@ const data3 = { ], }; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const removeMutiLayer: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [120.11155128479004, 30.24868703665976], zoom: 11, - }), + }, }); - scene.on('loaded', () => { - const layer = new PolygonLayer({}) - .source(data1) - .scale('density', { - type: 'quantile', - }) - .color('#1990ff1a') - .shape('fill'); - scene.addLayer(layer); - const layer2 = new PolygonLayer({}) - .source(data2) - .scale('density', { - type: 'quantile', - }) - .color('#1990ff1a') - .shape('fill'); - scene.addLayer(layer2); + const layer = new PolygonLayer({}) + .source(data1) + .scale('density', { + type: 'quantile', + }) + .color('#1990ff1a') + .shape('fill'); + scene.addLayer(layer); - const layer3 = new PolygonLayer({}) - .source(data3) - .scale('density', { - type: 'quantile', - }) - .color('#1990ff1a') - .shape('fill'); - scene.addLayer(layer3); + const layer2 = new PolygonLayer({}) + .source(data2) + .scale('density', { + type: 'quantile', + }) + .color('#1990ff1a') + .shape('fill'); + scene.addLayer(layer2); - setTimeout(() => { - const layers = scene.getLayers(); - for (const layer of layers) { - scene.removeLayer(layer); - } - }, 2000); - }); -} + const layer3 = new PolygonLayer({}) + .source(data3) + .scale('density', { + type: 'quantile', + }) + .color('#1990ff1a') + .shape('fill'); + scene.addLayer(layer3); + + removeMutiLayer.extendGUI = (gui) => { + return [ + gui.add( + { + removeLayer: () => { + const layers = scene.getLayers(); + for (const layer of layers) { + scene.removeLayer(layer); + } + }, + }, + 'removeLayer', + ), + ]; + }; + + return scene; +}; diff --git a/examples/demos/bugfix/set-color.ts b/examples/demos/bugfix/set-color.ts new file mode 100644 index 00000000000..6520d3587d0 --- /dev/null +++ b/examples/demos/bugfix/set-color.ts @@ -0,0 +1,54 @@ +import { LineLayer, PolygonLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const setColor: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [-96, 37.8], + zoom: 3, + }, + }); + + const data = await fetch( + // 'https://gw.alipayobjects.com/os/basement_prod/d36ad90e-3902-4742-b8a2-d93f7e5dafa2.json' + 'https://mdn.alipayobjects.com/afts/file/A*CFbnRqXpg8wAAAAAAAAAAAAADrd2AQ/test.json', + ).then((res) => res.json()); + + const layer = new PolygonLayer({ autoFit: true }) + .source(data) + .color('#f00') + .shape('fill') + .active(true); + const layer2 = new LineLayer({ + zIndex: 2, + }) + .source(data) + .color('#ffffff') + .active(true) + .size(1) + .style({ + lineType: 'dash', + dashArray: [2, 2], + }); + scene.addLayer(layer); + scene.addLayer(layer2); + + setColor.extendGUI = (gui) => { + return [ + gui.add( + { + setColor: () => { + layer.color('#f0f'); + layer2.color('#00f'); + scene.render(); + }, + }, + 'setColor', + ), + ]; + }; + + return scene; +}; diff --git a/examples/demos/bugfix/set-data.ts b/examples/demos/bugfix/set-data.ts index d62e4005cea..517aa4b3a66 100644 --- a/examples/demos/bugfix/set-data.ts +++ b/examples/demos/bugfix/set-data.ts @@ -1,6 +1,6 @@ -import { PolygonLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { PolygonLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; const data1 = { type: 'FeatureCollection', @@ -60,35 +60,42 @@ const data2 = { ], }; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const setData: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [120.100535, 30.041909], zoom: 14.83, - }), + }, }); - scene.on('loaded', () => { - const layer = new PolygonLayer({ - autoFit: false, - }) - .source(data1) - .shape('fill') - .active(true) - .color('red'); + const layer = new PolygonLayer({ + autoFit: false, + }) + .source(data1) + .shape('fill') + .active(true) + .color('red'); - layer.once('inited', () => { - layer.fitBounds({ animate: false }); - }); + layer.once('inited', () => { + layer.fitBounds({ animate: false }); + }); - scene.addLayer(layer); + scene.addLayer(layer); - setTimeout(() => { - console.log('setData: '); - layer.setData(data2); - }, 2000); - }); -} + setData.extendGUI = (gui) => { + return [ + gui.add( + { + setData: () => { + console.log('setData: '); + layer.setData(data2); + }, + }, + 'setData', + ), + ]; + }; + + return scene; +}; diff --git a/examples/demos/bugfix/set-size.ts b/examples/demos/bugfix/set-size.ts new file mode 100644 index 00000000000..6e8b068209d --- /dev/null +++ b/examples/demos/bugfix/set-size.ts @@ -0,0 +1,69 @@ +import { PointLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const setSize: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [121.435159, 31.256971], + zoom: 14.89, + minZoom: 10, + }, + }); + + const data = await fetch( + 'https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json', + ).then((res) => res.json()); + + const pointLayer = new PointLayer({}) + .source(data, { + parser: { + type: 'json', + x: 'longitude', + y: 'latitude', + }, + }) + .shape('name', [ + 'circle', + 'triangle', + 'square', + 'pentagon', + 'hexagon', + 'octogon', + 'hexagram', + 'rhombus', + 'vesica', + ]) + .size('unit_price', [10, 25]) + .active(true) + .color('name', ['#5B8FF9', '#5CCEA1', '#5D7092', '#F6BD16', '#E86452']) + .style({ + opacity: 1, + strokeWidth: 2, + }); + + scene.addLayer(pointLayer); + scene.on('zoomchange', () => { + console.log('zoomchange'); + }); + scene.setZoom(15); + + setSize.extendGUI = (gui) => { + return [ + gui.add( + { + setSize: () => { + console.log('start update'); + pointLayer.size(30); + scene.render(); + console.log('update'); + }, + }, + 'setSize', + ), + ]; + }; + + return scene; +}; diff --git a/examples/demos/bugfix/size.ts b/examples/demos/bugfix/size.ts deleted file mode 100644 index 60175d97e9f..00000000000 --- a/examples/demos/bugfix/size.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { PointLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; - -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', - center: [121.435159, 31.256971], - zoom: 14.89, - minZoom: 10, - }), - }); - scene.on('loaded', () => { - fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json') - .then((res) => res.json()) - .then((data) => { - const pointLayer = new PointLayer({}) - .source(data, { - parser: { - type: 'json', - x: 'longitude', - y: 'latitude', - }, - }) - .shape('name', [ - 'circle', - 'triangle', - 'square', - 'pentagon', - 'hexagon', - 'octogon', - 'hexagram', - 'rhombus', - 'vesica', - ]) - .size('unit_price', [10, 25]) - .active(true) - .color('name', ['#5B8FF9', '#5CCEA1', '#5D7092', '#F6BD16', '#E86452']) - .style({ - opacity: 1, - strokeWidth: 2, - }); - - scene.addLayer(pointLayer); - scene.on('zoomchange', () => { - console.log('zoomchange'); - }); - scene.setZoom(15); - setTimeout(() => { - console.log('start update'); - pointLayer.size(30); - scene.render(); - console.log('update'); - }, 1000); - }); - }); -} diff --git a/examples/demos/bugfix/text-offsets.ts b/examples/demos/bugfix/text-offsets.ts new file mode 100644 index 00000000000..011b5f92c9c --- /dev/null +++ b/examples/demos/bugfix/text-offsets.ts @@ -0,0 +1,53 @@ +import { PointLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const textOffsets: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [121.434765, 31.256735], + zoom: 14.83, + }, + }); + + const data = await fetch( + 'https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json', + ).then((res) => res.json()); + + const circleLayer = new PointLayer() + .source(data, { + parser: { + type: 'json', + x: 'longitude', + y: 'latitude', + }, + }) + .shape('circle') + .color('#0f0') + .size(5); + const imageLayerText = new PointLayer() + .source(data, { + parser: { + type: 'json', + x: 'longitude', + y: 'latitude', + }, + }) + .shape('name', 'text') + .color('#f00') + .size(10) + .style({ + textOffset: { + field: 'count', + value: (v: number) => { + return [0, v * 14]; + }, + }, + }); + + scene.addLayer(imageLayerText); + scene.addLayer(circleLayer); + + return scene; +}; diff --git a/examples/demos/bugfix/text_offsets.ts b/examples/demos/bugfix/text_offsets.ts deleted file mode 100644 index 71e3f527030..00000000000 --- a/examples/demos/bugfix/text_offsets.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { PointLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; - -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', - center: [121.434765, 31.256735], - zoom: 14.83, - }), - }); - scene.on('loaded', () => { - fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json') - .then((res) => res.json()) - .then((data) => { - const circleLayer = new PointLayer() - .source(data, { - parser: { - type: 'json', - x: 'longitude', - y: 'latitude', - }, - }) - .shape('circle') - .color('#0f0') - .size(5); - const imageLayerText = new PointLayer() - .source(data, { - parser: { - type: 'json', - x: 'longitude', - y: 'latitude', - }, - }) - .shape('name', 'text') - .color('#f00') - .size(10) - .style({ - textOffset: { - field: 'count', - value: (v) => { - return [0, v * 14]; - }, - }, - }); - scene.addLayer(imageLayerText); - scene.addLayer(circleLayer); - - if (window['screenshot']) { - window['screenshot'](); - } - }); - }); -} diff --git a/examples/demos/bugfix/tile_update.ts b/examples/demos/bugfix/tile-update.ts similarity index 51% rename from examples/demos/bugfix/tile_update.ts rename to examples/demos/bugfix/tile-update.ts index ee1827661c7..73732173647 100644 --- a/examples/demos/bugfix/tile_update.ts +++ b/examples/demos/bugfix/tile-update.ts @@ -1,22 +1,21 @@ -import { RasterLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { RasterLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const tileUpdate: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [121.434765, 31.256735], zoom: 2, - }), + }, }); const url1 = 'https://tiles{1-3}.geovisearth.com/base/v1/ter/{z}/{x}/{y}?format=webp&tmsIds=w&token=b2a0cfc132cd60b61391b9dd63c15711eadb9b38a9943e3f98160d5710aef788'; const url2 = 'https://tiles{1-3}.geovisearth.com/base/v1/cat/{z}/{x}/{y}?format=png&tmsIds=w&token=b2a0cfc132cd60b61391b9dd63c15711eadb9b38a9943e3f98160d5710aef788'; + const layer1 = new RasterLayer({ zIndex: 1, }).source(url1, { @@ -27,11 +26,21 @@ export function MapRender(options: RenderDemoOptions) { }, }); - scene.on('loaded', () => { - scene.addLayer(layer1); - setTimeout(() => { - layer1.setData(url2); - console.log('update'); - }, 1000); - }); -} + scene.addLayer(layer1); + + tileUpdate.extendGUI = (gui) => { + return [ + gui.add( + { + setData: () => { + layer1.setData(url2); + console.log('update'); + }, + }, + 'setData', + ), + ]; + }; + + return scene; +}; diff --git a/examples/demos/bugfix/touch-event.ts b/examples/demos/bugfix/touch-event.ts new file mode 100644 index 00000000000..3624790d005 --- /dev/null +++ b/examples/demos/bugfix/touch-event.ts @@ -0,0 +1,48 @@ +import { PolygonLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const touchEvent: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [-96, 37.8], + zoom: 3, + }, + }); + + const data = await fetch( + 'https://mdn.alipayobjects.com/afts/file/A*CFbnRqXpg8wAAAAAAAAAAAAADrd2AQ/test.json', + ).then((res) => res.json()); + + const layer = new PolygonLayer({ autoFit: true }) + .source(data) + .color('#f00') + .shape('fill') + .active(true); + + scene.addLayer(layer); + // layer.on('touchstart',(e)=>{ + // console.log('touchstart',e) + + // }) + + // layer.on('touchend',(e)=>{ + // console.log('touchend',e) + + // }) + // layer.on('panmove',(e)=>{ + // console.log('touchmove',e) + + // }) + layer.on('touchmove', (e) => { + console.log('touchmove', e); + }); + + // layer.on('mouseup',()=>{ + // alert('mouseup') + + // }) + + return scene; +}; diff --git a/examples/demos/bugfix/touchend.ts b/examples/demos/bugfix/touchend.ts deleted file mode 100644 index cda3c0eb047..00000000000 --- a/examples/demos/bugfix/touchend.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { PolygonLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; - -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', - center: [-96, 37.8], - zoom: 3, - }), - }); - scene.on('loaded', () => { - fetch( - // 'https://gw.alipayobjects.com/os/basement_prod/d36ad90e-3902-4742-b8a2-d93f7e5dafa2.json' - 'https://mdn.alipayobjects.com/afts/file/A*CFbnRqXpg8wAAAAAAAAAAAAADrd2AQ/test.json', - ) - .then((res) => res.json()) - .then((data) => { - console.log(data); - const layer = new PolygonLayer({ autoFit: true }) - .source(data) - .color('#f00') - .shape('fill') - .active(true); - - scene.addLayer(layer); - // layer.on('touchstart',(e)=>{ - // console.log('touchstart',e) - - // }) - - // layer.on('touchend',(e)=>{ - // console.log('touchend',e) - - // }) - // layer.on('panmove',(e)=>{ - // console.log('touchmove',e) - - // }) - layer.on('touchmove', (e) => { - console.log('touchmove', e); - }); - - // layer.on('mouseup',()=>{ - // alert('mouseup') - - // }) - }); - }); -} diff --git a/examples/demos/canvas/event.ts b/examples/demos/canvas/event.ts index 6d3431919c8..a278325d6f3 100644 --- a/examples/demos/canvas/event.ts +++ b/examples/demos/canvas/event.ts @@ -1,52 +1,51 @@ -import { CanvasLayer, PointLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; +import { CanvasLayer, PointLayer } from '@antv/l7'; import * as turf from '@turf/turf'; -import type { RenderDemoOptions } from '../../types'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -const POSITION = [120.104697, 30.260704] as [number, number]; +export const event: TestCase = async (options) => { + const POSITION = [120.104697, 30.260704] as [number, number]; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', + const scene = await CaseScene({ + ...options, + mapConfig: { center: POSITION, zoom: 14.89, minZoom: 10, - }), + }, + }); + + const canvasLayer = new CanvasLayer({ + zIndex: 4, + draw: ({ canvas, ctx, container, utils }) => { + const context = ctx as CanvasRenderingContext2D; + context.clearRect(0, 0, container.width, container.height); + context.fillStyle = 'blue'; + const { x, y } = utils.lngLatToContainer(POSITION); + const size = 36 * window.devicePixelRatio; + context.fillRect(x - size / 2, y - size / 2, size, size); + }, }); - scene.on('loaded', () => { - const canvasLayer = new CanvasLayer({ - zIndex: 4, - draw: ({ canvas, ctx, container, utils }) => { - const context = ctx as CanvasRenderingContext2D; - context.clearRect(0, 0, container.width, container.height); - context.fillStyle = 'blue'; - const { x, y } = utils.lngLatToContainer(POSITION); - const size = 36 * window.devicePixelRatio; - context.fillRect(x - size / 2, y - size / 2, size, size); - }, - }); - scene.addLayer(canvasLayer); + scene.addLayer(canvasLayer); - canvasLayer.on('add', () => { - canvasLayer.layerModel.canvas?.addEventListener('click', (e) => { - console.log('canvas click', e); - }); + canvasLayer.on('add', () => { + canvasLayer.layerModel.canvas?.addEventListener('click', (e) => { + console.log('canvas click', e); }); + }); - const pointLayer = new PointLayer({}); - pointLayer - .source(turf.featureCollection([turf.point(POSITION)])) - .color('red') - .shape('circle') - .size(30); - scene.addLayer(pointLayer); + const pointLayer = new PointLayer({}); + pointLayer + .source(turf.featureCollection([turf.point(POSITION)])) + .color('red') + .shape('circle') + .size(30); + scene.addLayer(pointLayer); - pointLayer.on('click', (e) => { - console.log('layer click', e); - }); + pointLayer.on('click', (e) => { + console.log('layer click', e); }); -} + + return scene; +}; diff --git a/examples/demos/canvas/index.ts b/examples/demos/canvas/index.ts index 9b436909566..066a5e603f2 100644 --- a/examples/demos/canvas/index.ts +++ b/examples/demos/canvas/index.ts @@ -1,2 +1,2 @@ -export { MapRender as event } from './event'; -export { MapRender as layer } from './layer'; +export { event } from './event'; +export { layer } from './layer'; diff --git a/examples/demos/canvas/layer.ts b/examples/demos/canvas/layer.ts index cb2c0a85416..25718f86c39 100644 --- a/examples/demos/canvas/layer.ts +++ b/examples/demos/canvas/layer.ts @@ -1,58 +1,61 @@ -import { CanvasLayer, PointLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; +import { CanvasLayer, PointLayer } from '@antv/l7'; import * as turf from '@turf/turf'; -import type { RenderDemoOptions } from '../../types'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; const POSITION = [120.104697, 30.260704] as [number, number]; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - // map: new allMap['GoogleMap']({ - style: 'light', +export const layer: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: POSITION, zoom: 14.89, minZoom: 10, - }), + }, }); - scene.on('loaded', () => { - const canvasLayer = new CanvasLayer({ - zIndex: 4, - draw: ({ canvas, ctx, container, utils }) => { - const context = ctx as CanvasRenderingContext2D; - context.clearRect(0, 0, container.width, container.height); - context.fillStyle = 'blue'; - const { x, y } = utils.lngLatToContainer(POSITION); - const size = 36 * window.devicePixelRatio; - context.fillRect(x - size / 2, y - size / 2, size, size); - }, - }); - scene.addLayer(canvasLayer); - const pointLayer = new PointLayer({}); - pointLayer - .source(turf.featureCollection([turf.point(POSITION)])) - .color('red') - .shape('circle') - .size(30); - scene.addLayer(pointLayer); + const canvasLayer = new CanvasLayer({ + zIndex: 4, + draw: ({ canvas, ctx, container, utils }) => { + const context = ctx as CanvasRenderingContext2D; + context.clearRect(0, 0, container.width, container.height); + context.fillStyle = 'blue'; + const { x, y } = utils.lngLatToContainer(POSITION); + const size = 36 * window.devicePixelRatio; + context.fillRect(x - size / 2, y - size / 2, size, size); + }, + }); + scene.addLayer(canvasLayer); - const showBtn = document.createElement('button'); - showBtn.innerHTML = 'Show CanvasLayer'; - showBtn.style = 'position: absolute; left: 20px; z-index: 10; top: 60px;'; - showBtn.onclick = () => { - canvasLayer.show(); - }; + const pointLayer = new PointLayer({}); + pointLayer + .source(turf.featureCollection([turf.point(POSITION)])) + .color('red') + .shape('circle') + .size(30); + scene.addLayer(pointLayer); - const hideBtn = document.createElement('button'); - hideBtn.innerHTML = 'Hide CanvasLayer'; - hideBtn.style = 'position: absolute; left: 20px; z-index: 10; top: 90px;'; - hideBtn.onclick = () => { - canvasLayer.hide(); - }; + layer.extendGUI = (gui) => { + return [ + gui.add( + { + 'Show CanvasLayer': () => { + canvasLayer.show(); + }, + }, + 'Show CanvasLayer', + ), + gui.add( + { + 'Hide CanvasLayer': () => { + canvasLayer.hide(); + }, + }, + 'Hide CanvasLayer', + ), + ]; + }; - document.body.append(showBtn, hideBtn); - }); -} + return scene; +}; diff --git a/examples/demos/components/control.ts b/examples/demos/components/control.ts deleted file mode 100644 index 6f349506abf..00000000000 --- a/examples/demos/components/control.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { PointLayer, Scene, Zoom } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; - -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'dark', - center: [121.46552, 31.223009], - zoom: 19, - }), - }); - - fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json') - .then((res) => res.json()) - .then((data) => { - const imageLayerText = new PointLayer() - .source( - [ - { - longitude: 121.46552, - latitude: 31.223009, - }, - ], - { - parser: { - type: 'json', - x: 'longitude', - y: 'latitude', - }, - }, - ) - .shape('circle') - .color('#f00') - .size(10) - .style({ - opacity: 0.8, - }); - scene.addLayer(imageLayerText); - }); - - const newControl = new Zoom({ - showZoom: true, - }); - scene.addControl(newControl); - // @ts-ignore - window.scene = scene; - scene.on('loaded', () => { - console.log(scene.getZoom()); - }); -} diff --git a/examples/demos/components/index.ts b/examples/demos/components/index.ts index fa227e6b038..5d004171d10 100644 --- a/examples/demos/components/index.ts +++ b/examples/demos/components/index.ts @@ -1,5 +1,5 @@ -export { MapRender as control } from './control'; -export { MapRender as layerPopup } from './layerPopup'; -export { MapRender as marker } from './marker'; -export { MapRender as popup } from './popup'; -export { MapRender as swipe } from './swipe'; +export { layerPopup } from './layer-popup'; +export { marker } from './marker'; +export { popup } from './popup'; +export { swipe } from './swipe'; +export { zoom } from './zoom'; diff --git a/examples/demos/components/layer-popup.ts b/examples/demos/components/layer-popup.ts new file mode 100644 index 00000000000..bbd55ea0f64 --- /dev/null +++ b/examples/demos/components/layer-popup.ts @@ -0,0 +1,61 @@ +import { LayerPopup, PointLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const layerPopup: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [121.435159, 31.256971], + zoom: 14.89, + minZoom: 10, + }, + }); + + const data = await fetch( + 'https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json', + ).then((res) => res.json()); + + const pointLayer = new PointLayer({ + name: 'layer', + }) + .source(data, { + parser: { + type: 'json', + x: 'longitude', + y: 'latitude', + }, + }) + .shape('name', [ + 'circle', + 'triangle', + 'square', + 'pentagon', + 'hexagon', + 'octogon', + 'hexagram', + 'rhombus', + 'vesica', + ]) + .size('unit_price', [10, 25]) + .color('name', ['#5B8FF9', '#5CCEA1', '#5D7092', '#F6BD16', '#E86452']) + .style({ + opacity: 1, + strokeWidth: 2, + }); + + scene.addLayer(pointLayer); + + const layerPopup = new LayerPopup({ + items: [ + { + layer: 'layer', + fields: ['name', 'count'], + }, + ], + }); + + scene.addPopup(layerPopup); + + return scene; +}; diff --git a/examples/demos/components/layerPopup.ts b/examples/demos/components/layerPopup.ts deleted file mode 100644 index b33202b427e..00000000000 --- a/examples/demos/components/layerPopup.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { LayerPopup, PointLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; - -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap.GaodeMap({ - style: 'light', - center: [121.435159, 31.256971], - zoom: 14.89, - minZoom: 10, - }), - }); - scene.on('loaded', () => { - fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json') - .then((res) => res.json()) - .then((data) => { - const pointLayer = new PointLayer({ - name: 'layer', - }) - .source(data, { - parser: { - type: 'json', - x: 'longitude', - y: 'latitude', - }, - }) - .shape('name', [ - 'circle', - 'triangle', - 'square', - 'pentagon', - 'hexagon', - 'octogon', - 'hexagram', - 'rhombus', - 'vesica', - ]) - .size('unit_price', [10, 25]) - .color('name', ['#5B8FF9', '#5CCEA1', '#5D7092', '#F6BD16', '#E86452']) - .style({ - opacity: 1, - strokeWidth: 2, - }); - - scene.addLayer(pointLayer); - - const layerPopup = new LayerPopup({ - items: [ - { - layer: 'layer', - fields: ['name', 'count'], - }, - ], - }); - - scene.addPopup(layerPopup); - }); - }); -} diff --git a/examples/demos/components/marker.ts b/examples/demos/components/marker.ts index 00b80656269..6de161b34b4 100644 --- a/examples/demos/components/marker.ts +++ b/examples/demos/components/marker.ts @@ -1,37 +1,46 @@ -import { Marker, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { Marker } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const marker: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [121.434765, 31.256735], zoom: 3, - }), + }, }); - scene.on('loaded', () => { - addMarkers(); - scene.render(); - setTimeout(() => { - scene.setZoom(5); - }, 2000); - }); - function addMarkers() { - fetch('https://gw.alipayobjects.com/os/basement_prod/67f47049-8787-45fc-acfe-e19924afe032.json') - .then((res) => res.json()) - .then((nodes) => { - for (let i = 0; i < nodes.length; i++) { - if (nodes[i].g !== '1' || nodes[i].v === '') { - continue; - } + const nodes = await fetch( + 'https://gw.alipayobjects.com/os/basement_prod/67f47049-8787-45fc-acfe-e19924afe032.json', + ).then((res) => res.json()); + + for (let i = 0; i < nodes.length; i++) { + if (nodes[i].g !== '1' || nodes[i].v === '') { + continue; + } - const marker = new Marker().setLnglat({ lng: nodes[i].x * 1, lat: nodes[i].y }); - scene.addMarker(marker); - } - }); + const markerIns = new Marker({ draggable: true }).setLnglat({ + lng: Number(nodes[i].x * 1), + lat: Number(nodes[i].y), + }); + scene.addMarker(markerIns); } -} + + scene.render(); + + marker.extendGUI = (gui) => { + return [ + gui.add( + { + setZoom: () => { + scene.setZoom(5); + }, + }, + 'setZoom', + ), + ]; + }; + + return scene; +}; diff --git a/examples/demos/components/popup.ts b/examples/demos/components/popup.ts index 8f2a66e6b33..6a4c239c261 100644 --- a/examples/demos/components/popup.ts +++ b/examples/demos/components/popup.ts @@ -1,36 +1,45 @@ -import { Popup, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { Popup } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap.GaodeMap({ - style: 'light', +export const popup: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [121.435159, 31.256971], zoom: 14.89, minZoom: 10, - }), + }, }); - scene.on('loaded', () => { - const popup = new Popup({ - lngLat: { - lng: 121.435159, - lat: 31.256971, - }, - html: '
123456
', - className: String(Math.random()), - style: `z-index: ${String(Math.random())}`, - }); - setInterval(() => { - popup.setOptions({ - className: String(Math.random()), - style: `z-index: ${String(Math.floor(Math.random() * 100))}`, - }); - }, 2000); - - scene.addPopup(popup); + const popupIns = new Popup({ + lngLat: { + lng: 121.435159, + lat: 31.256971, + }, + html: '
123456
', + className: String(Math.random()), + style: `z-index: ${String(Math.random())}`, }); -} + + scene.addPopup(popupIns); + + popup.extendGUI = (gui) => { + return [ + gui.add( + { + setOptions: () => { + popupIns.setOptions({ + className: String(Math.random()), + html: '
789
', + style: `z-index: ${String(Math.floor(Math.random() * 100))}`, + }); + }, + }, + 'setOptions', + ), + ]; + }; + + return scene; +}; diff --git a/examples/demos/components/swipe.ts b/examples/demos/components/swipe.ts index 5ba0b014c51..5cd57160bfb 100644 --- a/examples/demos/components/swipe.ts +++ b/examples/demos/components/swipe.ts @@ -1,117 +1,120 @@ -import { RasterLayer, Scene, Swipe } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; +import { RasterLayer, Swipe } from '@antv/l7'; import * as GeoTIFF from 'geotiff'; -import type { RenderDemoOptions } from '../../types'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const swipe: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [121.434765, 31.256735], zoom: 14.83, - }), + }, }); - async function getTiffData(url: string) { - const response = await fetch(url); - const arrayBuffer = await response.arrayBuffer(); - const tiff = await GeoTIFF.fromArrayBuffer(arrayBuffer); - const image = await tiff.getImage(); - const width = image.getWidth(); - const height = image.getHeight(); - const values = await image.readRasters(); - return { - data: values[0], - width, - height, - }; - } - scene.on('loaded', async () => { - const colors = [ - '#d73027', - '#f46d43', - '#fdae61', - '#fee08b', - '#d9ef8b', - '#a6d96a', - '#66bd63', - '#1a9850', - ]; - const ndvi1 = await getTiffData( + const colors = [ + '#d73027', + '#f46d43', + '#fdae61', + '#fee08b', + '#d9ef8b', + '#a6d96a', + '#66bd63', + '#1a9850', + ]; + + const [ndvi1, ndvi2] = await Promise.all([ + await getTiffData( 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/file/A*sZpWQZK21NIAAAAAAAAAAAAADmJ7AQ/ndvi2022-03-01.glb', - ); - const ndvi2 = await getTiffData( + ), + getTiffData( 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/file/A*JeHQTIzN4_kAAAAAAAAAAAAADmJ7AQ/ndvi2022-10-01.NDVI.glb', - ); + ), + ]); - // 影像地图图层 - const baseLayer = new RasterLayer({ zIndex: -1 }).source( - 'https://www.google.com/maps/vt?lyrs=s@189&gl=cn&x={x}&y={y}&z={z}', - { - parser: { - type: 'rasterTile', - tileSize: 256, - zoomOffset: 0, - }, + // 影像地图图层 + const baseLayer = new RasterLayer({ zIndex: -1 }).source( + 'https://www.google.com/maps/vt?lyrs=s@189&gl=cn&x={x}&y={y}&z={z}', + { + parser: { + type: 'rasterTile', + tileSize: 256, + zoomOffset: 0, }, - ); + }, + ); - const leftLayer = new RasterLayer({ - autoFit: true, + const leftLayer = new RasterLayer({ + autoFit: true, + }) + .source(ndvi1.data, { + parser: { + type: 'raster', + width: ndvi1.width, + height: ndvi1.height, + extent: [-112.117293306503, 32.78212288135407, -111.77216057434428, 33.10568277278276], + }, }) - .source(ndvi1.data, { - parser: { - type: 'raster', - width: ndvi1.width, - height: ndvi1.height, - extent: [-112.117293306503, 32.78212288135407, -111.77216057434428, 33.10568277278276], - }, - }) - .style({ - clampLow: false, - clampHigh: false, - domain: [-1, 1], - nodataValue: 0, - rampColors: { - type: 'linear', - positions: [-0.4, -0.2, 0, 0.2, 0.4, 0.6, 0.8, 1.0], // 数据需要换成 0-1 - colors: colors, - }, - }); + .style({ + clampLow: false, + clampHigh: false, + domain: [-1, 1], + nodataValue: 0, + rampColors: { + type: 'linear', + positions: [-0.4, -0.2, 0, 0.2, 0.4, 0.6, 0.8, 1.0], // 数据需要换成 0-1 + colors: colors, + }, + }); - const rightLayer = new RasterLayer({}) - .source(ndvi2.data, { - parser: { - type: 'raster', - width: ndvi2.width, - height: ndvi2.height, - extent: [-112.117293306503, 32.78212288135407, -111.77216057434428, 33.10568277278276], - }, - }) - .style({ - clampLow: false, - clampHigh: false, - domain: [-1, 1], - nodataValue: 0, - rampColors: { - type: 'linear', - positions: [-0.4, -0.2, 0, 0.2, 0.4, 0.6, 0.8, 1.0], // 数据需要换成 0-1 - colors: colors, - }, - }); + const rightLayer = new RasterLayer({}) + .source(ndvi2.data, { + parser: { + type: 'raster', + width: ndvi2.width, + height: ndvi2.height, + extent: [-112.117293306503, 32.78212288135407, -111.77216057434428, 33.10568277278276], + }, + }) + .style({ + clampLow: false, + clampHigh: false, + domain: [-1, 1], + nodataValue: 0, + rampColors: { + type: 'linear', + positions: [-0.4, -0.2, 0, 0.2, 0.4, 0.6, 0.8, 1.0], // 数据需要换成 0-1 + colors: colors, + }, + }); - scene.addLayer(baseLayer); - scene.addLayer(leftLayer); - scene.addLayer(rightLayer); + scene.addLayer(baseLayer); + scene.addLayer(leftLayer); + scene.addLayer(rightLayer); - const swipe = new Swipe({ - orientation: 'vertical', - ratio: 0.5, - layers: [leftLayer], - rightLayers: [rightLayer], - }); - scene.addControl(swipe); + const mySwipe = new Swipe({ + orientation: 'vertical', + ratio: 0.5, + layers: [leftLayer], + rightLayers: [rightLayer], }); + + scene.addControl(mySwipe); + + return scene; +}; + +async function getTiffData(url: string) { + const response = await fetch(url); + const arrayBuffer = await response.arrayBuffer(); + const tiff = await GeoTIFF.fromArrayBuffer(arrayBuffer); + const image = await tiff.getImage(); + const width = image.getWidth(); + const height = image.getHeight(); + const values = await image.readRasters(); + return { + data: values[0], + width, + height, + }; } diff --git a/examples/demos/components/zoom.ts b/examples/demos/components/zoom.ts new file mode 100644 index 00000000000..66cf8e22671 --- /dev/null +++ b/examples/demos/components/zoom.ts @@ -0,0 +1,45 @@ +import { PointLayer, Zoom } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const zoom: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [121.46552, 31.223009], + zoom: 19, + }, + }); + + const imageLayerText = new PointLayer() + .source( + [ + { + longitude: 121.46552, + latitude: 31.223009, + }, + ], + { + parser: { + type: 'json', + x: 'longitude', + y: 'latitude', + }, + }, + ) + .shape('circle') + .color('#f00') + .size(10) + .style({ + opacity: 0.8, + }); + + scene.addLayer(imageLayerText); + + const newControl = new Zoom({ + showZoom: true, + }); + scene.addControl(newControl); + + return scene; +}; diff --git a/examples/demos/extend/index.ts b/examples/demos/extend/index.ts new file mode 100644 index 00000000000..d8a54bbf8c0 --- /dev/null +++ b/examples/demos/extend/index.ts @@ -0,0 +1 @@ +export { threeGeometry } from './three-geometry'; diff --git a/examples/demos/extend/three-geometry.ts b/examples/demos/extend/three-geometry.ts new file mode 100644 index 00000000000..77cfc9d7747 --- /dev/null +++ b/examples/demos/extend/three-geometry.ts @@ -0,0 +1,265 @@ +import { ThreeLayer, ThreeRender } from '@antv/l7-three'; +import * as THREE from 'three'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const threeGeometry: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + style: 'dark', + center: [111.4453125, 32.84267363195431], + zoom: 12, + pitch: 45, + rotation: 0, + }, + }); + + scene.registerRenderService(ThreeRender); + + const threeJSLayer = new ThreeLayer({ + enableMultiPassRenderer: false, + onAddMeshes: (threeScene, layer) => { + // 当前场景的中心 + const center = scene.getCenter(); + + // 环境光照 + threeScene.add(new THREE.AmbientLight(0xffffff, 0.2)); + const sunlight = new THREE.DirectionalLight(0xff0000, 0.8); + layer.setObjectLngLat(sunlight, [center.lng + 0.3, center.lat + 0.08], 1000); + sunlight.matrixWorldNeedsUpdate = true; + threeScene.add(sunlight); + + const directionalLightHelper = new THREE.DirectionalLightHelper(sunlight, 5); + threeScene.add(directionalLightHelper); + + const box = createBoxGeometry(); + box.scale.set(1000, 1000, 1000); + box.rotation.set(0, 90, 0); + layer.setObjectLngLat(box, [center.lng - 0.05, center.lat], 0); + threeScene.add(box); + + const circle = createCircleGeometry(); + circle.scale.set(100, 100, 1000); + layer.setObjectLngLat(circle, [center.lng - 0.03, center.lat], 0); + threeScene.add(circle); + + const cylinder = createCylinderGeometry(); + cylinder.scale.set(100, 100, 100); + layer.setObjectLngLat(cylinder, [center.lng - 0.015, center.lat], 0); + threeScene.add(cylinder); + + const cone = createConeGeometry(); + cone.scale.set(100, 100, 100); + layer.setObjectLngLat(cone, [center.lng + 0.01, center.lat], 0); + threeScene.add(cone); + + const plane = createPlaneGeometry(); + plane.scale.set(1000, 1000, 1000); + layer.setObjectLngLat(plane, [center.lng + 0.03, center.lat], 0); + threeScene.add(plane); + + const shape = createShape(); + shape.scale.set(100, 100, 100); + layer.setObjectLngLat(shape, [center.lng + 0.03, center.lat], 0); + threeScene.add(shape); + + const sphere = createSphereGeometry(); + sphere.scale.set(10, 10, 10); + layer.setObjectLngLat(sphere, [center.lng + 0.07, center.lat], 0); + threeScene.add(sphere); + + const tube = createTube(); + tube.scale.set(100, 100, 100); + layer.setObjectLngLat(tube, [center.lng + 0.07, center.lat], 0); + threeScene.add(tube); + + const points = createPoints(); + points.scale.set(100, 100, 100); + layer.setObjectLngLat(points, [center.lng + 0.11, center.lat], 0); + threeScene.add(points); + + const line = createLine(); + line.scale.set(100, 100, 100); + layer.setObjectLngLat(line, [center.lng + 0.13, center.lat], 0); + threeScene.add(line); + + const camera = layer.threeRenderService.getRenderCamera(); + const cameraHelper = createCameraHelper(camera); + layer.setObjectLngLat(plane, [center.lng, center.lat], 0); + threeScene.add(cameraHelper); + }, + }).animate(true); + scene.addLayer(threeJSLayer); + + return scene; +}; + +function createBoxGeometry() { + const geometry = new THREE.BoxGeometry(1, 1, 1); + const material = new THREE.MeshPhongMaterial({ + color: 0xffffff, + reflectivity: 0.8, + shininess: 80, + emissive: 0x049ef4, + specular: 0x049ef4, + }); + const cube = new THREE.Mesh(geometry, material); + return cube; +} + +function createCircleGeometry() { + const geometry = new THREE.CircleGeometry(5, 32); + const material = new THREE.MeshPhongMaterial({ + color: 0xffffff, + reflectivity: 0.8, + shininess: 80, + emissive: 0x049ef4, + specular: 0x049ef4, + }); + const circle = new THREE.Mesh(geometry, material); + return circle; +} + +function createCylinderGeometry() { + const geometry = new THREE.CylinderGeometry(5, 5, 20, 32); + const material = new THREE.MeshPhongMaterial({ + color: 0xffffff, + reflectivity: 0.8, + shininess: 80, + emissive: 0x049ef4, + specular: 0x049ef4, + }); + const cylinder = new THREE.Mesh(geometry, material); + return cylinder; +} + +function createConeGeometry() { + const geometry = new THREE.ConeGeometry(5, 20, 32); + const material = new THREE.MeshPhongMaterial({ + color: 0xffffff, + reflectivity: 0.8, + shininess: 80, + emissive: 0x049ef4, + specular: 0x049ef4, + }); + const cone = new THREE.Mesh(geometry, material); + return cone; +} + +function createPlaneGeometry() { + const geometry = new THREE.PlaneGeometry(1, 1); + const material = new THREE.MeshPhongMaterial({ + color: 0xffffff, + reflectivity: 0.8, + shininess: 80, + emissive: 0x049ef4, + specular: 0x049ef4, + }); + const plane = new THREE.Mesh(geometry, material); + return plane; +} + +function createShape() { + const x = 0, + y = 0; + + const heartShape = new THREE.Shape(); + + heartShape.moveTo(x + 5, y + 5); + heartShape.bezierCurveTo(x + 5, y + 5, x + 4, y, x, y); + heartShape.bezierCurveTo(x - 6, y, x - 6, y + 7, x - 6, y + 7); + heartShape.bezierCurveTo(x - 6, y + 11, x - 3, y + 15.4, x + 5, y + 19); + heartShape.bezierCurveTo(x + 12, y + 15.4, x + 16, y + 11, x + 16, y + 7); + heartShape.bezierCurveTo(x + 16, y + 7, x + 16, y, x + 10, y); + heartShape.bezierCurveTo(x + 7, y, x + 5, y + 5, x + 5, y + 5); + + const geometry = new THREE.ShapeGeometry(heartShape); + const material = new THREE.MeshPhongMaterial({ + color: 0xffffff, + reflectivity: 0.8, + shininess: 80, + emissive: 0x049ef4, + specular: 0x049ef4, + }); + const mesh = new THREE.Mesh(geometry, material); + return mesh; +} + +function createSphereGeometry() { + const geometry = new THREE.SphereGeometry(15, 32, 16); + const material = new THREE.MeshPhongMaterial({ + color: 0xffffff, + reflectivity: 0.8, + shininess: 80, + emissive: 0x049ef4, + specular: 0x049ef4, + }); + const sphere = new THREE.Mesh(geometry, material); + return sphere; +} + +function createTube() { + class CustomSinCurve extends THREE.Curve { + public scale: number; + constructor(scale = 1) { + super(); + this.scale = scale; + } + + getPoint(t: number, optionalTarget = new THREE.Vector3()) { + const tx = t * 3 - 1.5; + const ty = Math.sin(2 * Math.PI * t); + const tz = 0; + return optionalTarget.set(tx, ty, tz).multiplyScalar(this.scale); + } + } + + const path = new CustomSinCurve(10); + const geometry = new THREE.TubeGeometry(path, 20, 2, 8, false); + const material = new THREE.MeshPhongMaterial({ + color: 0xffffff, + reflectivity: 0.8, + shininess: 80, + emissive: 0x049ef4, + specular: 0x049ef4, + }); + const mesh = new THREE.Mesh(geometry, material); + return mesh; +} + +function createCameraHelper(camera?: THREE.Camera) { + const cameraObj = + camera ?? new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); + const helper = new THREE.CameraHelper(cameraObj); + return helper; +} + +function createPoints() { + const points = []; + points.push(new THREE.Vector3(-10, 0, 0)); + points.push(new THREE.Vector3(0, 10, 0)); + points.push(new THREE.Vector3(10, 0, 0)); + + const geometry = new THREE.BufferGeometry().setFromPoints(points); + const material = new THREE.PointsMaterial({ size: 200, color: 0x049ef4 }); + const pointsGeometry = new THREE.Points(geometry, material); + return pointsGeometry; +} + +function createLine() { + const material = new THREE.LineBasicMaterial({ + color: 0x049ef4, + linewidth: 6, + }); + + const points = []; + points.push(new THREE.Vector3(-10, 0, 0)); + points.push(new THREE.Vector3(0, 10, 0)); + points.push(new THREE.Vector3(10, 0, 0)); + + const geometry = new THREE.BufferGeometry().setFromPoints(points); + + const line = new THREE.Line(geometry, material); + return line; +} diff --git a/examples/demos/gallery/fujian.ts b/examples/demos/gallery/fujian.ts index e2ed6ad04be..abb7e15baac 100644 --- a/examples/demos/gallery/fujian.ts +++ b/examples/demos/gallery/fujian.ts @@ -1,272 +1,266 @@ -import { PointLayer, PolygonLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { PointLayer, PolygonLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const fujian: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [121.434765, 31.256735], zoom: 14.83, - }), + }, }); - scene.on('loaded', async () => { + await Promise.all([ scene.addImage( 'province', 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*hvqeQa9I6ccAAAAAAAAAAAAADmJ7AQ/original', - ); + ), scene.addImage( 'city', 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*sBlgRp8Ah7sAAAAAAAAAAAAADmJ7AQ/original', - ); + ), scene.addImage( 'county', 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*ufrWTqCNCScAAAAAAAAAAAAADmJ7AQ/original', - ); - // 获取数据 - const dataList = [ - // 市级行政区 - 'https://mdn.alipayobjects.com/afts/file/A*jPjCTad_s24AAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA.json', - // 市级行政区一级群列岛名 - 'https://mdn.alipayobjects.com/afts/file/A*HW8yQb2joA8AAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E4%B8%80%E7%BA%A7%E7%BE%A4%E5%88%97%E5%B2%9B%E5%90%8D.json', - ///市级行政区一级河流名.json - 'https://mdn.alipayobjects.com/afts/file/A*EjtNRrENGToAAAAAAAAAAAAADrd2AQ/市级行政区一级河流名.json', - //市级行政区一级港湾名.json - 'https://mdn.alipayobjects.com/afts/file/A*lqxATobbMLwAAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E4%B8%80%E7%BA%A7%E6%B8%AF%E6%B9%BE%E5%90%8D.json', - //市级行政区一级岛屿名.json - 'https://mdn.alipayobjects.com/afts/file/A*xyeHRZCF8DsAAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E4%B8%80%E7%BA%A7%E5%B2%9B%E5%B1%BF%E5%90%8D.json', - //市级行政区县级行政中心.json - 'https://mdn.alipayobjects.com/afts/file/A*vrDfSrB8J4sAAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E5%8E%BF%E7%BA%A7%E8%A1%8C%E6%94%BF%E4%B8%AD%E5%BF%83.json', - //市级行政区县级行政区.json - 'https://mdn.alipayobjects.com/afts/file/A*lfffQ5ej7AEAAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E5%8E%BF%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA.json', - // 市级行政区省级行政中心.json - 'https://mdn.alipayobjects.com/afts/file/A*jtlsTqxTJkoAAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E7%9C%81%E7%BA%A7%E8%A1%8C%E6%94%BF%E4%B8%AD%E5%BF%83.json', - //市级行政区山峰.json - 'https://mdn.alipayobjects.com/afts/file/A*DRSfRqBs9qsAAAAAAAAAAAAADrd2AQ/市级行政区山峰.json', - //市级行政区色带.json - 'https://mdn.alipayobjects.com/afts/file/A*KRD4QbjkZCMAAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E8%89%B2%E5%B8%A6.json', - //市级行政区面状水域.json - 'https://mdn.alipayobjects.com/afts/file/A*3e9nSJwXqu0AAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E9%9D%A2%E7%8A%B6%E6%B0%B4%E5%9F%9F.json', - //市级行政区境界线.json - 'https://mdn.alipayobjects.com/afts/file/A*tA8nSqhulQQAAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E5%A2%83%E7%95%8C%E7%BA%BF.json', - //市级行政区河流.json - 'https://mdn.alipayobjects.com/afts/file/A*2vGmRrYpTjEAAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E6%B2%B3%E6%B5%81.json', - //市级行政区海岸线.json - 'https://mdn.alipayobjects.com/afts/file/A*juI9TpBcQ74AAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E6%B5%B7%E5%B2%B8%E7%BA%BF.json', - //市级行政区二级群列岛名.json - 'https://mdn.alipayobjects.com/afts/file/A*E4ReSqdYq-cAAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E4%BA%8C%E7%BA%A7%E7%BE%A4%E5%88%97%E5%B2%9B%E5%90%8D.json', - //市级行政区地级市行政中心.json - 'https://mdn.alipayobjects.com/afts/file/A*I3HSQaYyQ_UAAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E5%9C%B0%E7%BA%A7%E5%B8%82%E8%A1%8C%E6%94%BF%E4%B8%AD%E5%BF%83.json', - //市级行政区大型水库名.json - 'https://mdn.alipayobjects.com/afts/file/A*xxXKTpte0VUAAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E5%A4%A7%E5%9E%8B%E6%B0%B4%E5%BA%93%E5%90%8D.json', - ]; + ), + ]); - const result = await Promise.all(dataList.map(async (url) => await (await fetch(url)).json())); - const cityLayer = new PolygonLayer({ - autoFit: true, + // 获取数据 + const dataList = [ + // 市级行政区 + 'https://mdn.alipayobjects.com/afts/file/A*jPjCTad_s24AAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA.json', + // 市级行政区一级群列岛名 + 'https://mdn.alipayobjects.com/afts/file/A*HW8yQb2joA8AAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E4%B8%80%E7%BA%A7%E7%BE%A4%E5%88%97%E5%B2%9B%E5%90%8D.json', + ///市级行政区一级河流名.json + 'https://mdn.alipayobjects.com/afts/file/A*EjtNRrENGToAAAAAAAAAAAAADrd2AQ/市级行政区一级河流名.json', + //市级行政区一级港湾名.json + 'https://mdn.alipayobjects.com/afts/file/A*lqxATobbMLwAAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E4%B8%80%E7%BA%A7%E6%B8%AF%E6%B9%BE%E5%90%8D.json', + //市级行政区一级岛屿名.json + 'https://mdn.alipayobjects.com/afts/file/A*xyeHRZCF8DsAAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E4%B8%80%E7%BA%A7%E5%B2%9B%E5%B1%BF%E5%90%8D.json', + //市级行政区县级行政中心.json + 'https://mdn.alipayobjects.com/afts/file/A*vrDfSrB8J4sAAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E5%8E%BF%E7%BA%A7%E8%A1%8C%E6%94%BF%E4%B8%AD%E5%BF%83.json', + //市级行政区县级行政区.json + 'https://mdn.alipayobjects.com/afts/file/A*lfffQ5ej7AEAAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E5%8E%BF%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA.json', + // 市级行政区省级行政中心.json + 'https://mdn.alipayobjects.com/afts/file/A*jtlsTqxTJkoAAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E7%9C%81%E7%BA%A7%E8%A1%8C%E6%94%BF%E4%B8%AD%E5%BF%83.json', + //市级行政区山峰.json + 'https://mdn.alipayobjects.com/afts/file/A*DRSfRqBs9qsAAAAAAAAAAAAADrd2AQ/市级行政区山峰.json', + //市级行政区色带.json + 'https://mdn.alipayobjects.com/afts/file/A*KRD4QbjkZCMAAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E8%89%B2%E5%B8%A6.json', + //市级行政区面状水域.json + 'https://mdn.alipayobjects.com/afts/file/A*3e9nSJwXqu0AAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E9%9D%A2%E7%8A%B6%E6%B0%B4%E5%9F%9F.json', + //市级行政区境界线.json + 'https://mdn.alipayobjects.com/afts/file/A*tA8nSqhulQQAAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E5%A2%83%E7%95%8C%E7%BA%BF.json', + //市级行政区河流.json + 'https://mdn.alipayobjects.com/afts/file/A*2vGmRrYpTjEAAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E6%B2%B3%E6%B5%81.json', + //市级行政区海岸线.json + 'https://mdn.alipayobjects.com/afts/file/A*juI9TpBcQ74AAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E6%B5%B7%E5%B2%B8%E7%BA%BF.json', + //市级行政区二级群列岛名.json + 'https://mdn.alipayobjects.com/afts/file/A*E4ReSqdYq-cAAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E4%BA%8C%E7%BA%A7%E7%BE%A4%E5%88%97%E5%B2%9B%E5%90%8D.json', + //市级行政区地级市行政中心.json + 'https://mdn.alipayobjects.com/afts/file/A*I3HSQaYyQ_UAAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E5%9C%B0%E7%BA%A7%E5%B8%82%E8%A1%8C%E6%94%BF%E4%B8%AD%E5%BF%83.json', + //市级行政区大型水库名.json + 'https://mdn.alipayobjects.com/afts/file/A*xxXKTpte0VUAAAAAAAAAAAAADrd2AQ/%E5%B8%82%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E5%A4%A7%E5%9E%8B%E6%B0%B4%E5%BA%93%E5%90%8D.json', + ]; + + const result = await Promise.all(dataList.map(async (url) => await (await fetch(url)).json())); + const cityLayer = new PolygonLayer({ + autoFit: true, + }) + .source(result[6]) + .shape('fill') + .scale('COLOR', { + type: 'cat', + domain: ['Y', 'P', 'G', 'R'], }) - .source(result[6]) - .shape('fill') - .scale('COLOR', { - type: 'cat', - domain: ['Y', 'P', 'G', 'R'], - }) - .color('COLOR', ['#f7f6c6', '#fceaea', '#e0e7d5', '#f3e4cf']); + .color('COLOR', ['#f7f6c6', '#fceaea', '#e0e7d5', '#f3e4cf']); - // 陆上轮廓 - const layer2 = new PolygonLayer().source(result[9]).shape('fill').color('#b4cad7'); + // 陆上轮廓 + const layer2 = new PolygonLayer().source(result[9]).shape('fill').color('#b4cad7'); - // 水域 - const waterLayer = new PolygonLayer().source(result[10]).shape('fill').color('#bcebfe'); - // 面状河流线 - const waterLayerLine = new PolygonLayer() - .source(result[10]) - .shape('line') - .size(0.5) - .color('#50aac8'); + // 水域 + const waterLayer = new PolygonLayer().source(result[10]).shape('fill').color('#bcebfe'); + // 面状河流线 + const waterLayerLine = new PolygonLayer() + .source(result[10]) + .shape('line') + .size(0.5) + .color('#50aac8'); - // 线河流线 - const river_Line = new PolygonLayer() - .source(result[12]) - .shape('line') - .size(0.5) - .color('#50aac8'); - // 群岛标注图层 - const island_name = new PointLayer({ - minZoom: 8, - }) - .source(result[1]) - .shape('NAME', 'text') - .size(15) - .color('#3b474e'); + // 线河流线 + const river_Line = new PolygonLayer().source(result[12]).shape('line').size(0.5).color('#50aac8'); + // 群岛标注图层 + const island_name = new PointLayer({ + minZoom: 8, + }) + .source(result[1]) + .shape('NAME', 'text') + .size(15) + .color('#3b474e'); - // 河流标注图层 - const river_name = new PointLayer({ minZoom: 5 }) - .source(result[2]) - .shape('NAME', 'text') - .size(15) - .color('#4aa1bd') - .style({ - fontWeight: 800, - }); - // 港湾标注 - const gangwan_name = new PointLayer({ - minZoom: 6, - }) - .source(result[3]) - .shape('NAME', 'text') - .size(15) - .color('#4eaed9') - .style({ - fontWeight: 800, - }); - // 海岛 - const island_name1 = new PointLayer({ - minZoom: 7, - }) - .source(result[4]) - .shape('NAME', 'text') - .size(15) - .color('#3b474e') - .style({ - fontWeight: 600, - }); + // 河流标注图层 + const river_name = new PointLayer({ minZoom: 5 }) + .source(result[2]) + .shape('NAME', 'text') + .size(15) + .color('#4aa1bd') + .style({ + fontWeight: 800, + }); + // 港湾标注 + const gangwan_name = new PointLayer({ + minZoom: 6, + }) + .source(result[3]) + .shape('NAME', 'text') + .size(15) + .color('#4eaed9') + .style({ + fontWeight: 800, + }); + // 海岛 + const island_name1 = new PointLayer({ + minZoom: 7, + }) + .source(result[4]) + .shape('NAME', 'text') + .size(15) + .color('#3b474e') + .style({ + fontWeight: 600, + }); - // 县界 - const county_Line = new PolygonLayer({ - minZoom: 5, - }) - .source(result[11]) - .shape('line') - .size(0.3) - .color('#a59f97'); - // 城市界 - const city_Line = new PolygonLayer().source(result[0]).shape('line').size(0.5).color('#787269'); + // 县界 + const county_Line = new PolygonLayer({ + minZoom: 5, + }) + .source(result[11]) + .shape('line') + .size(0.3) + .color('#a59f97'); + // 城市界 + const city_Line = new PolygonLayer().source(result[0]).shape('line').size(0.5).color('#787269'); - // 海岸线 - const sea_Line = new PolygonLayer().source(result[13]).shape('line').size(0.5).color('#50aac8'); + // 海岸线 + const sea_Line = new PolygonLayer().source(result[13]).shape('line').size(0.5).color('#50aac8'); - // 城市标注 - const cityName = new PointLayer({ - maxZoom: 8, - minZoom: 5, - }) - .source(result[15]) - .shape('NAME', 'text') - .size(14) - .color('#000') - .style({ - fontWeight: 800, - textAnchor: 'top', - textOffset: [0, 12], - }); + // 城市标注 + const cityName = new PointLayer({ + maxZoom: 8, + minZoom: 5, + }) + .source(result[15]) + .shape('NAME', 'text') + .size(14) + .color('#000') + .style({ + fontWeight: 800, + textAnchor: 'top', + textOffset: [0, 12], + }); - // 城市点位 + // 城市点位 - const cityPoint = new PointLayer({ - maxZoom: 7, - minZoom: 5, - }) - .source(result[15]) - .shape('city') - .size(5); + const cityPoint = new PointLayer({ + maxZoom: 7, + minZoom: 5, + }) + .source(result[15]) + .shape('city') + .size(5); - // 省级市标注 - const provinceCityName = new PointLayer({ - minZoom: 5, - maxZoom: 7, - }) - .source(result[7]) - .shape('NAME', 'text') - .size(14) - .color('#000') - .style({ - fontWeight: 800, - textAnchor: 'top', - textOffset: [0, 12], - }); + // 省级市标注 + const provinceCityName = new PointLayer({ + minZoom: 5, + maxZoom: 7, + }) + .source(result[7]) + .shape('NAME', 'text') + .size(14) + .color('#000') + .style({ + fontWeight: 800, + textAnchor: 'top', + textOffset: [0, 12], + }); - // 省级市点位 - const provincePoint = new PointLayer({ - minZoom: 5, - maxZoom: 7, - }) - .source(result[7]) - .shape('province') - .size(5); + // 省级市点位 + const provincePoint = new PointLayer({ + minZoom: 5, + maxZoom: 7, + }) + .source(result[7]) + .shape('province') + .size(5); - // 县标注 - const countyName = new PointLayer({ - minZoom: 8, - }) - .source(result[5]) - .shape('NAME', 'text') - .size(14) - .color('#333') - .style({ - fontWeight: 600, - textAnchor: 'top', - textOffset: [0, 12], - }); - 7; - // 县点位 - const countyPoint = new PointLayer({ - minZoom: 8, - }) - .source(result[5]) - .shape('county') - .size(5); + // 县标注 + const countyName = new PointLayer({ + minZoom: 8, + }) + .source(result[5]) + .shape('NAME', 'text') + .size(14) + .color('#333') + .style({ + fontWeight: 600, + textAnchor: 'top', + textOffset: [0, 12], + }); + 7; + // 县点位 + const countyPoint = new PointLayer({ + minZoom: 8, + }) + .source(result[5]) + .shape('county') + .size(5); - // 县标注 - const mountainPoint = new PointLayer({ - minZoom: 6, - }) - .source(result[8]) - .shape('triangle') - .size(6) - .color('#326648'); + // 县标注 + const mountainPoint = new PointLayer({ + minZoom: 6, + }) + .source(result[8]) + .shape('triangle') + .size(6) + .color('#326648'); - // 山标注 - const mountainPoint_name = new PointLayer({ - minZoom: 6, - }) - .source(result[8]) - .shape('NAME', 'text') - .size(14) - .color('#326648') - .style({ - fontWeight: 800, - textAnchor: 'top', - textOffset: [0, 12], - }); + // 山标注 + const mountainPoint_name = new PointLayer({ + minZoom: 6, + }) + .source(result[8]) + .shape('NAME', 'text') + .size(14) + .color('#326648') + .style({ + fontWeight: 800, + textAnchor: 'top', + textOffset: [0, 12], + }); - scene.addLayer(cityLayer); - scene.addLayer(layer2); - scene.addLayer(waterLayer); - scene.addLayer(waterLayerLine); - scene.addLayer(river_Line); - scene.addLayer(county_Line); + scene.addLayer(cityLayer); + scene.addLayer(layer2); + scene.addLayer(waterLayer); + scene.addLayer(waterLayerLine); + scene.addLayer(river_Line); + scene.addLayer(county_Line); - scene.addLayer(city_Line); - scene.addLayer(sea_Line); + scene.addLayer(city_Line); + scene.addLayer(sea_Line); - scene.addLayer(cityName); - scene.addLayer(cityPoint); - scene.addLayer(countyName); - scene.addLayer(countyPoint); - scene.addLayer(provinceCityName); - scene.addLayer(provincePoint); - scene.addLayer(island_name); - scene.addLayer(island_name1); - scene.addLayer(gangwan_name); - scene.addLayer(river_name); - scene.addLayer(mountainPoint); - scene.addLayer(mountainPoint_name); - if (window['screenshot']) { - window['screenshot'](); - } - }); -} + scene.addLayer(cityName); + scene.addLayer(cityPoint); + scene.addLayer(countyName); + scene.addLayer(countyPoint); + scene.addLayer(provinceCityName); + scene.addLayer(provincePoint); + scene.addLayer(island_name); + scene.addLayer(island_name1); + scene.addLayer(gangwan_name); + scene.addLayer(river_name); + scene.addLayer(mountainPoint); + scene.addLayer(mountainPoint_name); + + return scene; +}; diff --git a/examples/demos/gallery/index.ts b/examples/demos/gallery/index.ts index d6077164542..47805ea4445 100644 --- a/examples/demos/gallery/index.ts +++ b/examples/demos/gallery/index.ts @@ -1 +1,2 @@ -export { MapRender as fujian } from './fujian'; +export { fujian } from './fujian'; +export { variFlight } from './vari-flight'; diff --git a/examples/demos/gallery/vari-flight.ts b/examples/demos/gallery/vari-flight.ts new file mode 100644 index 00000000000..5a1520a57a3 --- /dev/null +++ b/examples/demos/gallery/vari-flight.ts @@ -0,0 +1,108 @@ +import { LineLayer, PointLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const variFlight: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + style: 'dark', + center: [40, 40.16797], + zoom: 2.5, + }, + }); + + await scene.addImage( + 'plane', + 'https://gw.alipayobjects.com/zos/bmw-prod/0ca1668e-38c2-4010-8568-b57cb33839b9.svg', + ); + + const [world, dot, flyline] = await Promise.all([ + fetch( + 'https://gw.alipayobjects.com/os/bmw-prod/2960e1fc-b543-480f-a65e-d14c229dd777.json', + ).then((d) => d.json()), + fetch( + 'https://gw.alipayobjects.com/os/basement_prod/4472780b-fea1-4fc2-9e4b-3ca716933dc7.json', + ).then((d) => d.text()), + fetch( + 'https://gw.alipayobjects.com/os/basement_prod/a5ac7bce-181b-40d1-8a16-271356264ad8.json', + ).then((d) => d.text()), + ]); + + const dotData = eval(dot); + // @ts-ignore + const flydata = eval(flyline).map((item) => { + // @ts-ignore + const latlng1 = item.from.split(',').map((e) => { + return e * 1; + }); + // @ts-ignore + const latlng2 = item.to.split(',').map((e) => { + return e * 1; + }); + return { coord: [latlng1, latlng2] }; + }); + + const worldLine = new LineLayer().source(world).color('#41fc9d').size(0.5).style({ + opacity: 0.4, + }); + const dotPoint = new PointLayer() + .source(dotData, { + parser: { + type: 'json', + x: 'lng', + y: 'lat', + }, + }) + .shape('circle') + .color('#ffed11') + .animate({ enable: options.animate }) + .size(40); + const flyLine = new LineLayer({ blend: 'normal' }) + .source(flydata, { + parser: { + type: 'json', + coordinates: 'coord', + }, + }) + .color('#ff6b34') + .texture('plane') + .shape('arc') + .size(15) + .animate( + !options.animate + ? { enable: false } + : { + duration: 1, + interval: 0.2, + trailLength: 0.5, + }, + ) + .style({ + textureBlend: 'replace', + lineTexture: true, // 开启线的贴图功能 + iconStep: 10, // 设置贴图纹理的间距 + }); + + const flyLine2 = new LineLayer() + .source(flydata, { + parser: { + type: 'json', + coordinates: 'coord', + }, + }) + .color('#ff6b34') + .shape('arc') + .size(1) + .style({ + lineType: 'dash', + dashArray: [5, 5], + opacity: 0.5, + }); + scene.addLayer(worldLine); + scene.addLayer(dotPoint); + scene.addLayer(flyLine2); + scene.addLayer(flyLine); + + return scene; +}; diff --git a/examples/demos/geometry/index.ts b/examples/demos/geometry/index.ts new file mode 100644 index 00000000000..fc2c12d597d --- /dev/null +++ b/examples/demos/geometry/index.ts @@ -0,0 +1,4 @@ +export { plane } from './plane'; +export { rain } from './rain'; +export { snow } from './snow'; +export { terrain } from './terrain'; diff --git a/examples/demos/geometry/plane.ts b/examples/demos/geometry/plane.ts new file mode 100644 index 00000000000..f2455be5b6c --- /dev/null +++ b/examples/demos/geometry/plane.ts @@ -0,0 +1,28 @@ +import { GeometryLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const plane: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [120.1025, 30.2594], + style: 'dark', + zoom: 10, + }, + }); + + const layer = new GeometryLayer() + .shape('plane') + .style({ + opacity: 0.8, + width: 0.074, + height: 0.061, + center: [120.1025, 30.2594], + }) + .active(true) + .color('#ff0'); + scene.addLayer(layer); + + return scene; +}; diff --git a/examples/demos/geometry/rain.ts b/examples/demos/geometry/rain.ts new file mode 100644 index 00000000000..5e8faae4bcf --- /dev/null +++ b/examples/demos/geometry/rain.ts @@ -0,0 +1,33 @@ +import { GeometryLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const rain: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + pitch: 90, + style: 'dark', + center: [120, 30], + zoom: 6, + }, + }); + + const layer = new GeometryLayer() + .shape('sprite') + .size(10) + .style({ + opacity: 0.3, + mapTexture: + 'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*w2SFSZJp4nIAAAAAAAAAAAAAARQnAQ', // rain + center: [120, 30], + spriteCount: 120, + spriteRadius: 10, + spriteTop: 300, + spriteUpdate: 10, + spriteScale: 0.8, + }); + scene.addLayer(layer); + + return scene; +}; diff --git a/examples/demos/geometry/snow.ts b/examples/demos/geometry/snow.ts new file mode 100644 index 00000000000..8d7a59d7067 --- /dev/null +++ b/examples/demos/geometry/snow.ts @@ -0,0 +1,31 @@ +import { GeometryLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const snow: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + pitch: 40, + style: 'dark', + center: [120, 30], + zoom: 6, + }, + }); + + const layer = new GeometryLayer() + .shape('sprite') + .size(10) + .style({ + mapTexture: + 'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*zLQwQKBSagYAAAAAAAAAAAAAARQnAQ', // snow + center: [120, 30], + spriteCount: 60, + spriteRadius: 10, + spriteTop: 300, + spriteUpdate: 5, + }); + scene.addLayer(layer); + + return scene; +}; diff --git a/examples/demos/geometry/terrain.ts b/examples/demos/geometry/terrain.ts new file mode 100644 index 00000000000..60f3f3cc8f6 --- /dev/null +++ b/examples/demos/geometry/terrain.ts @@ -0,0 +1,84 @@ +import { GeometryLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const terrain: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [120.1025, 30.2594], + style: 'dark', + pitch: 65, + rotation: 180, + zoom: 14, + }, + }); + + let currentZoom = 14, + currentModelData = '100x100'; + + const layer = new GeometryLayer().shape('plane').style({ + width: 0.074, + height: 0.061, + center: [120.1025, 30.2594], + widthSegments: 100, + heightSegments: 100, + terrainClipHeight: 1, + mapTexture: + 'https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*gA0NRbuOF5cAAAAAAAAAAAAAARQnAQ', + terrainTexture: + 'https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*eYFaRYlnnOUAAAAAAAAAAAAAARQnAQ', + rgb2height: (r, g, b) => { + let h = (r * 255.0 * 256.0 * 256.0 + g * 255.0 * 256.0 + b * 255.0) * 0.1; + h = h / 200 - 12750; + h = Math.max(0, h); + return h; + }, + }); + + let modelData10: any, modelData20: any, modelData100: any; + + layer.on('terrainImageLoaded', () => { + modelData10 = layer.layerModel.createModelData({ + widthSegments: 10, + heightSegments: 10, + }); + + modelData20 = layer.layerModel.createModelData({ + widthSegments: 20, + heightSegments: 20, + }); + + modelData100 = layer.layerModel.createModelData({ + widthSegments: 100, + heightSegments: 100, + }); + }); + + scene.on('zoom', () => { + const zoom = Math.floor(scene.getZoom()); + if (currentZoom !== zoom) { + if (zoom > 13) { + if (currentModelData !== '100x100') { + layer.updateModelData(modelData100); + currentModelData = '100x100'; + } + } else if (zoom > 12) { + if (currentModelData !== '20x20') { + layer.updateModelData(modelData20); + currentModelData = '20x20'; + } + } else { + if (currentModelData !== '10x10') { + layer.updateModelData(modelData10); + currentModelData = '10x10'; + } + } + currentZoom = zoom; + } + }); + + scene.addLayer(layer); + + return scene; +}; diff --git a/examples/demos/heatmap/grid.ts b/examples/demos/heatmap/grid.ts index e2bad16345b..d9580159787 100644 --- a/examples/demos/heatmap/grid.ts +++ b/examples/demos/heatmap/grid.ts @@ -1,65 +1,46 @@ -import { HeatmapLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { HeatmapLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const grid: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [121.434765, 31.256735], zoom: 14.83, - }), + }, }); - scene.on('loaded', () => { - fetch('https://gw.alipayobjects.com/os/basement_prod/d3564b06-670f-46ea-8edb-842f7010a7c6.json') - .then((res) => res.json()) - .then((data) => { - const layer = new HeatmapLayer({ autoFit: true }) - .source(data, { - transforms: [ - { - type: 'grid', - size: 150000, - field: 'mag', - method: 'sum', - }, - ], - }) - .size('sum', (sum) => { - return sum * 2000; - }) - .shape('hexagonColumn') - .style({ - coverage: 0.8, - angle: 0, - }) - .active(true) - .color( - 'count', - [ - '#0B0030', - '#100243', - '#100243', - '#1B048B', - '#051FB7', - '#0350C1', - '#0350C1', - '#0072C4', - '#0796D3', - '#2BA9DF', - '#30C7C4', - '#6BD5A0', - '#A7ECB2', - '#D0F4CA', - ].reverse(), - ); - scene.addLayer(layer); - if (window['screenshot']) { - window['screenshot'](); - } - }); - }); -} + const data = await fetch( + 'https://gw.alipayobjects.com/os/antfincdn/aBQAMIpvPL/qingdao_500m.csv', + ).then((res) => res.text()); + + const layer = new HeatmapLayer({ + autoFit: true, + }) + .source(data, { + parser: { type: 'csv', x: 'lng', y: 'lat' }, + transforms: [{ type: 'grid', size: 3000, field: 'count', method: 'sum' }], + }) + .shape('square') + .style({ + coverage: 0.9, + }) + .color( + 'count', + [ + '#FF3417', + '#FF7412', + '#FFB02A', + '#FFE754', + '#46F3FF', + '#02BEFF', + '#1A7AFF', + '#0A1FB2', + ].reverse(), + ); + + scene.addLayer(layer); + + return scene; +}; diff --git a/examples/demos/heatmap/hexagon.ts b/examples/demos/heatmap/hexagon.ts index 80b2e4405ab..3aa2770d6e8 100644 --- a/examples/demos/heatmap/hexagon.ts +++ b/examples/demos/heatmap/hexagon.ts @@ -1,60 +1,53 @@ -import { HeatmapLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { HeatmapLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const hexagon: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [121.434765, 31.256735], zoom: 14.83, - }), + }, }); - scene.on('loaded', () => { - fetch('https://gw.alipayobjects.com/os/basement_prod/513add53-dcb2-4295-8860-9e7aa5236699.json') - .then((res) => res.json()) - .then((data) => { - const layer = new HeatmapLayer({ autoFit: true }) - .source(data, { - transforms: [ - { - type: 'hexagon', - size: 100, - field: 'h12', - method: 'sum', - }, - ], - }) - .size('sum', [0, 60]) - .shape('squareColumn') - .style({ - opacity: 1, - }) - .active(true) - .color( - 'sum', - [ - '#094D4A', - '#146968', - '#1D7F7E', - '#289899', - '#34B6B7', - '#4AC5AF', - '#5FD3A6', - '#7BE39E', - '#A1EDB8', - '#CEF8D6', - ].reverse(), - ); - scene.startAnimate(); - scene.addLayer(layer); - scene.render(); - if (window['screenshot']) { - window['screenshot'](); - } - }); - }); -} + const data = await fetch( + 'https://gw.alipayobjects.com/os/basement_prod/513add53-dcb2-4295-8860-9e7aa5236699.json', + ).then((res) => res.json()); + + const layer = new HeatmapLayer({ autoFit: true }) + .source(data, { + transforms: [ + { + type: 'hexagon', + size: 100, + field: 'h12', + method: 'sum', + }, + ], + }) + .shape('hexagon') + .style({ + opacity: 1, + }) + .active(true) + .color( + 'sum', + [ + '#094D4A', + '#146968', + '#1D7F7E', + '#289899', + '#34B6B7', + '#4AC5AF', + '#5FD3A6', + '#7BE39E', + '#A1EDB8', + '#CEF8D6', + ].reverse(), + ); + + scene.addLayer(layer); + + return scene; +}; diff --git a/examples/demos/heatmap/index.ts b/examples/demos/heatmap/index.ts index 07bd3694da8..93a8fdc6b5a 100644 --- a/examples/demos/heatmap/index.ts +++ b/examples/demos/heatmap/index.ts @@ -1,3 +1,4 @@ -export { MapRender as grid } from './grid'; -export { MapRender as hexagon } from './hexagon'; -export { MapRender as normal } from './normal'; +export { grid } from './grid'; +export { hexagon } from './hexagon'; +export { normal } from './normal'; +export { normal3D } from './normal-3d'; diff --git a/examples/demos/heatmap/normal-3d.ts b/examples/demos/heatmap/normal-3d.ts new file mode 100644 index 00000000000..c348223019e --- /dev/null +++ b/examples/demos/heatmap/normal-3d.ts @@ -0,0 +1,34 @@ +import { HeatmapLayer } from '@antv/l7'; +import data from '../../data/globe-earthquake-mag.json'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const normal3D: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [121.434765, 31.256735], + zoom: 14.83, + }, + }); + + const layer = new HeatmapLayer({ autoFit: true }) + .source(data) + .shape('heatmap3d') + .size('mag', [0, 1.0]) // weight映射通道 + .style({ + intensity: 2, + radius: 20, + opacity: 1.0, + rampColors: { + colors: ['#FF4818', '#F7B74A', '#FFF598', '#91EABC', '#2EA9A1', '#206C7C'].reverse(), + positions: [0, 0.2, 0.4, 0.6, 0.8, 1.0], + }, + }); + scene.addLayer(layer); + layer.on('inited', () => { + console.log(layer.getLegend('color')); + }); + + return scene; +}; diff --git a/examples/demos/heatmap/normal.ts b/examples/demos/heatmap/normal.ts index 4ec34a620d5..f4bbc933bba 100644 --- a/examples/demos/heatmap/normal.ts +++ b/examples/demos/heatmap/normal.ts @@ -1,41 +1,34 @@ -import { HeatmapLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { HeatmapLayer } from '@antv/l7'; +import data from '../../data/globe-earthquake-mag.json'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const normal: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [121.434765, 31.256735], zoom: 14.83, - }), + }, }); - scene.on('loaded', () => { - fetch('https://gw.alipayobjects.com/os/basement_prod/d3564b06-670f-46ea-8edb-842f7010a7c6.json') - .then((res) => res.json()) - .then((data) => { - const layer = new HeatmapLayer({ autoFit: true }) - .source(data) - .shape('heatmap') - .size('mag', [0, 1.0]) // weight映射通道 - .style({ - intensity: 2, - radius: 20, - opacity: 1.0, - rampColors: { - colors: ['#FF4818', '#F7B74A', '#FFF598', '#91EABC', '#2EA9A1', '#206C7C'].reverse(), - positions: [0, 0.2, 0.4, 0.6, 0.8, 1.0], - }, - }); - scene.addLayer(layer); - layer.on('inited', () => { - console.log(layer.getLegend('color')); - }); - if (window['screenshot']) { - window['screenshot'](); - } - }); + + const layer = new HeatmapLayer({ autoFit: true }) + .source(data) + .shape('heatmap') + .size('mag', [0, 1.0]) // weight映射通道 + .style({ + intensity: 2, + radius: 20, + opacity: 1.0, + rampColors: { + colors: ['#FF4818', '#F7B74A', '#FFF598', '#91EABC', '#2EA9A1', '#206C7C'].reverse(), + positions: [0, 0.2, 0.4, 0.6, 0.8, 1.0], + }, + }); + scene.addLayer(layer); + layer.on('inited', () => { + console.log(layer.getLegend('color')); }); -} + + return scene; +}; diff --git a/examples/demos/index.ts b/examples/demos/index.ts index dae549e77b5..7dbbe74b081 100644 --- a/examples/demos/index.ts +++ b/examples/demos/index.ts @@ -1,64 +1,50 @@ -import * as BugFix from './bugfix'; -import * as CanvasDemos from './canvas'; -import * as Components from './components'; -import * as GalleryDemos from './gallery'; -import * as HeatmapDemos from './heatmap'; -import * as LineDemos from './line'; -import * as MaskDemos from './mask'; -import * as PointDemos from './point'; -import * as PolygonDemos from './polygon'; -import * as RasterDemos from './raster'; -import * as TileDemos from './tile'; -import * as GPUDemos from './webgpu'; +import type { TestCase } from '../types'; +import * as BasemapTestCases from './basemap'; +import * as BugfixTestCases from './bugfix'; +import * as CanvasTestCases from './canvas'; +import * as ComponentsTestCases from './components'; +import * as ExtendTestCases from './extend'; +import * as GalleryTestCases from './gallery'; +import * as GeometryTestCases from './geometry'; +import * as HeatmapTestCases from './heatmap'; +import * as LineTestCases from './line'; +import * as MaskTestCases from './mask'; +import * as PointTestCases from './point'; +import * as PolygonTestCases from './polygon'; +import * as RasterTestCases from './raster'; +import * as TileTestCases from './tile'; +import * as WebgpuTestCases from './webgpu'; -export default [ - { - name: 'BugFix', - demos: BugFix, - }, - { - name: 'Point', - demos: PointDemos, - }, - { - name: 'Line', - demos: LineDemos, - }, - { - name: 'Polygon', - demos: PolygonDemos, - }, - { - name: 'Components', - demos: Components, - }, - { - name: 'Heatmap', - demos: HeatmapDemos, - }, - { - name: 'Raster', - demos: RasterDemos, - }, - { - name: 'Tile', - demos: TileDemos, - }, - { - name: 'Mask', - demos: MaskDemos, - }, - { - name: 'WebGPU', - demos: GPUDemos, - snapShot: false, - }, - { - name: 'Gallery', - demos: GalleryDemos, - }, - { - name: 'Canvas', - demos: CanvasDemos, - }, -]; +export const TestCases = new Map([ + ['bugfix', Object.entries(BugfixTestCases)], + ['point', Object.entries(PointTestCases)], + ['heatmap', Object.entries(HeatmapTestCases)], + ['line', Object.entries(LineTestCases)], + ['polygon', Object.entries(PolygonTestCases)], + ['raster', Object.entries(RasterTestCases)], + ['tile', Object.entries(TileTestCases)], + ['mask', Object.entries(MaskTestCases)], + ['canvas', Object.entries(CanvasTestCases)], + ['basemap', Object.entries(BasemapTestCases)], + ['components', Object.entries(ComponentsTestCases)], + ['geometry', Object.entries(GeometryTestCases)], + ['gallery', Object.entries(GalleryTestCases)], + ['webgpu', Object.entries(WebgpuTestCases)], + ['extend', Object.entries(ExtendTestCases)], +]); + +/** + * ge SnapshotTests from namespace + */ +// export function geSnapshotTestsFromNamespace(namespace: string) { +// const testcases = TestCases.get(namespace); +// if (!testcases) return []; +// const demo = testcases +// .filter(([, demo]) => Boolean(demo.snapshot)) +// .map(([name, demo]) => ({ +// name, +// snapshot: Boolean(demo.snapshot), +// sleepTime: typeof demo?.snapshot === 'object' ? demo.snapshot?.sleepTime : undefined, +// })); +// return demo; +// } diff --git a/examples/demos/line/arc-3d.ts b/examples/demos/line/arc-3d.ts new file mode 100644 index 00000000000..e40bee9b0d8 --- /dev/null +++ b/examples/demos/line/arc-3d.ts @@ -0,0 +1,41 @@ +import { LineLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const arc3D: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + style: 'dark', + center: [104.34278, 41.12554], + zoom: 2.94888, + pitch: 0, + }, + }); + + const data = await fetch( + 'https://gw.alipayobjects.com/os/bmw-prod/e495c407-953b-44cc-8f77-87b9cf257578.json', + ).then((res) => res.json()); + + const layer = new LineLayer({}) + .source(data, { + parser: { + type: 'json', + x: 'from_lon', + y: 'from_lat', + x1: 'to_lon', + y1: 'to_lat', + }, + }) + .size(2) + .shape('arc3d') + .color('#FF7C6A') + .style({ + segmentNumber: 15, + opacity: 0.8, + }); + + scene.addLayer(layer); + + return scene; +}; diff --git a/examples/demos/line/arc.ts b/examples/demos/line/arc.ts index 2a79d00e2cd..9f8b0af6094 100644 --- a/examples/demos/line/arc.ts +++ b/examples/demos/line/arc.ts @@ -1,16 +1,14 @@ -import { LineLayer, PointLayer, Scene, Source } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { LineLayer, PointLayer, Source } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const arc: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [121.434765, 31.256735], zoom: 14.83, - }), + }, }); const geoData = { @@ -25,7 +23,7 @@ export function MapRender(options: RenderDemoOptions) { type: 'MultiLineString', coordinates: [ [ - [116.371436, 39.942372], + [116.43, 39.97], [121.467025, 31.2327], ], ], @@ -55,8 +53,6 @@ export function MapRender(options: RenderDemoOptions) { const source = new Source(geoData); const source2 = new Source(geoData2); - // scene.on('zoom', e => console.log(e)) - const layer = new LineLayer({ blend: 'normal', autoFit: true }) .source(source) .size(2) @@ -83,59 +79,20 @@ export function MapRender(options: RenderDemoOptions) { const point = new PointLayer({ blend: 'normal', zIndex: 1 }) .source( [ - { - lng: 116.43, - lat: 39.97, - }, - { - lng: 108.39, - lat: 22.91, - }, + { lng: 116.43, lat: 39.97 }, + { lng: 108.39, lat: 22.91 }, ], { - parser: { - type: 'json', - x: 'lng', - y: 'lat', - }, + parser: { type: 'json', x: 'lng', y: 'lat' }, }, ) .shape('circle') .size(10) .color('blue'); - const point2 = new PointLayer({ blend: 'normal', zIndex: 1 }) - .source( - [ - { - lng: 116.43, - lat: 39.97, - }, - { - lng: 108.39, - lat: 22.91, - }, - ], - { - parser: { - type: 'json', - x: 'lng', - y: 'lat', - }, - }, - ) - .shape('circle') - .size(100000) - .color('blue') - .style({ - opacity: 0.5, - unit: 'meter', - }); - scene.addLayer(point); - scene.addLayer(point2); + scene.addLayer(point); scene.addLayer(layer); scene.addLayer(layer2); - if (window['screenshot']) { - window['screenshot'](); - } -} + + return scene; +}; diff --git a/examples/demos/line/arc_plane.ts b/examples/demos/line/arc_plane.ts deleted file mode 100644 index 9e5274b4aeb..00000000000 --- a/examples/demos/line/arc_plane.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { LineLayer, PointLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; - -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', - center: [40, 40.16797], - zoom: 2.5, - }), - }); - - scene.addImage( - 'plane', - 'https://gw.alipayobjects.com/zos/bmw-prod/0ca1668e-38c2-4010-8568-b57cb33839b9.svg', - ); - scene.on('loaded', () => { - Promise.all([ - fetch( - 'https://gw.alipayobjects.com/os/bmw-prod/2960e1fc-b543-480f-a65e-d14c229dd777.json', - ).then((d) => d.json()), - fetch( - 'https://gw.alipayobjects.com/os/basement_prod/4472780b-fea1-4fc2-9e4b-3ca716933dc7.json', - ).then((d) => d.text()), - fetch( - 'https://gw.alipayobjects.com/os/basement_prod/a5ac7bce-181b-40d1-8a16-271356264ad8.json', - ).then((d) => d.text()), - ]).then(function onLoad([world, dot, flyline]) { - const dotData = eval(dot); - // @ts-ignore - const flydata = eval(flyline).map((item) => { - // @ts-ignore - const latlng1 = item.from.split(',').map((e) => { - return e * 1; - }); - // @ts-ignore - const latlng2 = item.to.split(',').map((e) => { - return e * 1; - }); - return { coord: [latlng1, latlng2] }; - }); - - const worldLine = new LineLayer().source(world).color('#41fc9d').size(0.5).style({ - opacity: 0.4, - }); - const dotPoint = new PointLayer() - .source(dotData, { - parser: { - type: 'json', - x: 'lng', - y: 'lat', - }, - }) - .shape('circle') - .color('#ffed11') - .animate({ enable: options.animate }) - .size(40); - const flyLine = new LineLayer({ blend: 'normal' }) - .source(flydata, { - parser: { - type: 'json', - coordinates: 'coord', - }, - }) - .color('#ff6b34') - .texture('plane') - .shape('arc') - .size(15) - .animate( - !options.animate - ? { enable: false } - : { - duration: 1, - interval: 0.2, - trailLength: 0.5, - }, - ) - .style({ - textureBlend: 'replace', - lineTexture: true, // 开启线的贴图功能 - iconStep: 10, // 设置贴图纹理的间距 - }); - - const flyLine2 = new LineLayer() - .source(flydata, { - parser: { - type: 'json', - coordinates: 'coord', - }, - }) - .color('#ff6b34') - .shape('arc') - .size(1) - .style({ - lineType: 'dash', - dashArray: [5, 5], - opacity: 0.5, - }); - scene.addLayer(worldLine); - scene.addLayer(dotPoint); - scene.addLayer(flyLine2); - scene.addLayer(flyLine); - if (window['screenshot']) { - window['screenshot'](); - } - }); - }); -} diff --git a/examples/demos/line/dash.ts b/examples/demos/line/dash.ts index 741608ccf49..88b8e386ecd 100644 --- a/examples/demos/line/dash.ts +++ b/examples/demos/line/dash.ts @@ -1,55 +1,52 @@ -import { LineLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { LineLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ +export const dash: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { style: 'light', center: [121.434765, 31.256735], zoom: 14.83, - }), + }, }); - scene.on('loaded', () => { - fetch('https://gw.alipayobjects.com/os/rmsportal/ZVfOvhVCzwBkISNsuKCc.json') - .then((res) => res.json()) - .then((data) => { - const layer = new LineLayer({ - autoFit: true, - }) - .source(data) - .size('ELEV', (h) => { - return [h % 50 === 0 ? 1.0 : 0.5, (h - 1400) * 20]; - }) - .shape('line') - .scale('ELEV', { - type: 'quantize', - }) - .style({ - lineType: 'dash', - opacity: 1, - dashArray: [5, 5], - heightfixed: true, - }) - .color('ELEV', [ - '#094D4A', - '#146968', - '#1D7F7E', - '#289899', - '#34B6B7', - '#4AC5AF', - '#5FD3A6', - '#7BE39E', - '#A1EDB8', - '#CEF8D6', - ]); - scene.addLayer(layer); - if (window['screenshot']) { - window['screenshot'](); - } - }); - }); -} + const data = await fetch( + 'https://gw.alipayobjects.com/os/rmsportal/ZVfOvhVCzwBkISNsuKCc.json', + ).then((res) => res.json()); + + const layer = new LineLayer({ + autoFit: true, + }) + .source(data) + .size('ELEV', (h) => { + return [h % 50 === 0 ? 1.0 : 0.5, (h - 1400) * 20]; + }) + .shape('line') + .scale('ELEV', { + type: 'quantize', + }) + .style({ + lineType: 'dash', + opacity: 1, + dashArray: [5, 5], + heightfixed: true, + }) + .color('ELEV', [ + '#094D4A', + '#146968', + '#1D7F7E', + '#289899', + '#34B6B7', + '#4AC5AF', + '#5FD3A6', + '#7BE39E', + '#A1EDB8', + '#CEF8D6', + ]); + + scene.addLayer(layer); + + return scene; +}; diff --git a/examples/demos/line/flow.ts b/examples/demos/line/flow.ts index ec7d2694150..f2ecee30b1f 100644 --- a/examples/demos/line/flow.ts +++ b/examples/demos/line/flow.ts @@ -1,122 +1,110 @@ -import { LineLayer, PointLayer, PolygonLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { LineLayer, PointLayer, PolygonLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const flow: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [8.654789284720719, 47.412606122294044], zoom: 5, - }), + }, }); - fetch('https://mdn.alipayobjects.com/afts/file/A*O7PBQoWAMP4AAAAAAAAAAAAADrd2AQ/locations.json') - .then((res) => res.json()) - .then((fill) => { - const filllayer = new PolygonLayer({ - autoFit: true, - }) - .source(fill) - .shape('fill') - .color('#aaa'); - scene.addLayer(filllayer); + const [fill, lineData] = await Promise.all([ + fetch( + 'https://mdn.alipayobjects.com/afts/file/A*O7PBQoWAMP4AAAAAAAAAAAAADrd2AQ/locations.json', + ).then((res) => res.json()), + fetch( + 'https://mdn.alipayobjects.com/afts/file/A*Q_x7TLOMcrAAAAAAAAAAAAAADrd2AQ/flows-2016.json', + ).then((res) => res.json()), + ]); - const pointdata = fill.features.map((item: any) => { - return item.properties; - }); + const filllayer = new PolygonLayer({ + autoFit: true, + }) + .source(fill) + .shape('fill') + .color('#aaa'); + scene.addLayer(filllayer); - const circleLayer = new PointLayer({ - zIndex: 1, - }) - .source(pointdata, { - parser: { - type: 'json', - coordinates: 'centroid', - }, - }) - .shape('circle') - .size(10) - .color('rgb(8, 64, 129)') - .style({ - stroke: '#fff', - strokeWidth: 2, - }); + const pointdata = fill.features.map((item: any) => { + return item.properties; + }); + + const circleLayer = new PointLayer({ + zIndex: 1, + }) + .source(pointdata, { + parser: { + type: 'json', + coordinates: 'centroid', + }, + }) + .shape('circle') + .size(10) + .color('rgb(8, 64, 129)') + .style({ + stroke: '#fff', + strokeWidth: 2, + }); - scene.addLayer(circleLayer); + scene.addLayer(circleLayer); - fetch( - 'https://mdn.alipayobjects.com/afts/file/A*Q_x7TLOMcrAAAAAAAAAAAAAADrd2AQ/flows-2016.json', - ) - .then((res) => res.json()) - .then((lineData) => { - const pointObj = {}; - pointdata.forEach((item: any) => { - pointObj[item.abbr] = item; - }); + const pointObj: Record = {}; + pointdata.forEach((item: any) => { + pointObj[item.abbr] = item; + }); - const oddata = lineData - .map((item: any) => { - return { - ...item, - coordinates: [pointObj[item.origin].centroid, pointObj[item.dest].centroid], - }; - }) - .sort((a: any, b: any) => { - return a.count - b.count; - }); + const oddata = lineData + .map((item: any) => { + return { + ...item, + coordinates: [pointObj[item.origin].centroid, pointObj[item.dest].centroid], + }; + }) + .sort((a: any, b: any) => { + return a.count - b.count; + }); - const layer = new LineLayer({ - zIndex: 0, - autoFit: true, - }) - .source(oddata, { - parser: { - type: 'json', - coordinates: 'coordinates', - }, - }) - .scale('count', { - type: 'quantile', - }) - .size('count', [0.5, 1, 2, 2, 2, 6, 8, 10]) - .shape('flowline') - .color('count', [ - '#fef6b5', - '#ffdd9a', - '#ffc285', - '#ffa679', - '#fa8a76', - '#f16d7a', - '#e15383', - ]) - .style({ - // symbol:{ - // target:'halfTriangle', - // source:'none', - // }, - opacity: { - field: 'count', - value: [0.2, 0.4, 0.6, 0.8], - }, - // opacity:1, - gapWidth: 1, - offsets: { - field: 'count', - value: () => { - return [20, 20]; - }, - }, // 支持数据映射 - strokeWidth: 1, - strokeOpacity: 1, - stroke: '#000', - }); - scene.addLayer(layer); - if (window['screenshot']) { - window['screenshot'](); - } - }); + const layer = new LineLayer({ + zIndex: 0, + autoFit: true, + }) + .source(oddata, { + parser: { + type: 'json', + coordinates: 'coordinates', + }, + }) + .scale('count', { + type: 'quantile', + }) + .size('count', [0.5, 1, 2, 2, 2, 6, 8, 10]) + .shape('flowline') + .color('count', ['#fef6b5', '#ffdd9a', '#ffc285', '#ffa679', '#fa8a76', '#f16d7a', '#e15383']) + .style({ + // symbol:{ + // target:'halfTriangle', + // source:'none', + // }, + opacity: { + field: 'count', + value: [0.2, 0.4, 0.6, 0.8], + }, + // opacity:1, + gapWidth: 1, + offsets: { + field: 'count', + value: () => { + return [20, 20]; + }, + }, // 支持数据映射 + strokeWidth: 1, + strokeOpacity: 1, + stroke: '#000', }); -} + scene.addLayer(layer); + + return scene; +}; diff --git a/examples/demos/line/greatcircle.ts b/examples/demos/line/greatcircle.ts new file mode 100644 index 00000000000..311bdd8e7da --- /dev/null +++ b/examples/demos/line/greatcircle.ts @@ -0,0 +1,46 @@ +import { LineLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const greatcircle: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + style: 'light', + center: [107.77791556935472, 35.443286920228644], + zoom: 2.9142882493605033, + }, + }); + + const data = await fetch( + 'https://gw.alipayobjects.com/os/rmsportal/UEXQMifxtkQlYfChpPwT.txt', + ).then((res) => res.text()); + + const layer = new LineLayer({ + blend: 'normal', + }) + .source(data, { + parser: { + type: 'csv', + x: 'lng1', + y: 'lat1', + x1: 'lng2', + y1: 'lat2', + }, + }) + .size(1) + .shape('greatcircle') + // .animate({ + // enable: true, + // interval: 0.1, + // trailLength: 0.5, + // duration: 2, + // }) + .color('#8C1EB2') + .style({ + opacity: 0.8, + }); + scene.addLayer(layer); + + return scene; +}; diff --git a/examples/demos/line/index.ts b/examples/demos/line/index.ts index 35487ecf8b1..baa3364075f 100644 --- a/examples/demos/line/index.ts +++ b/examples/demos/line/index.ts @@ -1,6 +1,8 @@ -export { MapRender as arc } from './arc'; -export { MapRender as arc_plane } from './arc_plane'; -export { MapRender as dash } from './dash'; -export { MapRender as flow } from './flow'; -export { MapRender as normal } from './normal'; -export { MapRender as wall } from './wall'; +export { arc } from './arc'; +export { arc3D } from './arc-3d'; +export { dash } from './dash'; +export { flow } from './flow'; +export { greatcircle } from './greatcircle'; +export { normal } from './normal'; +export { simple } from './simple'; +export { wall } from './wall'; diff --git a/examples/demos/line/normal.ts b/examples/demos/line/normal.ts index b203300ecb9..437b4603fa3 100644 --- a/examples/demos/line/normal.ts +++ b/examples/demos/line/normal.ts @@ -1,18 +1,17 @@ -import { LineLayer, Scene, Source } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { LineLayer, Source } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ +export const normal: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { style: 'light', center: [121.434765, 31.256735], zoom: 14.83, - }), + }, }); - console.log(111); + const geoData = { type: 'FeatureCollection', features: [ @@ -68,10 +67,7 @@ export function MapRender(options: RenderDemoOptions) { opacity: 0.6, }); - scene.on('loaded', () => { - scene.addLayer(layer); - if (window['screenshot']) { - window['screenshot'](); - } - }); -} + scene.addLayer(layer); + + return scene; +}; diff --git a/examples/demos/webgpu/line_normal.ts b/examples/demos/line/simple.ts similarity index 63% rename from examples/demos/webgpu/line_normal.ts rename to examples/demos/line/simple.ts index a554315951e..dc394c5b28f 100644 --- a/examples/demos/webgpu/line_normal.ts +++ b/examples/demos/line/simple.ts @@ -1,20 +1,17 @@ -// @ts-ignore -import { LineLayer, Scene, Source } from '@antv/l7'; -// @ts-ignore -import * as allMap from '@antv/l7-maps'; +import { LineLayer, Source } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(option: { map: string; renderer: string }) { - const scene = new Scene({ - id: 'map', - renderer: option.renderer, - enableWebGPU: true, - shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', - map: new allMap[option.map || 'Map']({ +export const simple: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { style: 'light', center: [121.434765, 31.256735], zoom: 14.83, - }), + }, }); + const geoData = { type: 'FeatureCollection', features: [ @@ -61,21 +58,13 @@ export function MapRender(option: { map: string; renderer: string }) { ], }; const source = new Source(geoData); - const layer = new LineLayer({ blend: 'normal', autoFit: true }) + const layer = new LineLayer({ autoFit: true }) .source(source) .size(1) - .shape('line') - .color('#f00') - .style({ - opacity: 0.6, - }); + .shape('simple') + .color('#f00'); - scene.on('loaded', () => { - scene.addLayer(layer); - }); + scene.addLayer(layer); - setTimeout(() => { - layer.size(20); - scene.render(); - }, 2000); -} + return scene; +}; diff --git a/examples/demos/line/wall.ts b/examples/demos/line/wall.ts index 8faa3377eeb..e7ca3e44a56 100644 --- a/examples/demos/line/wall.ts +++ b/examples/demos/line/wall.ts @@ -1,32 +1,32 @@ -import { LineLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { LineLayer } from '@antv/l7'; +import data from '../../data/hunan-citys.json'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const wall: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [121.434765, 31.256735], zoom: 14.83, - }), + pitch: 45, + }, }); - fetch('https://gw.alipayobjects.com/os/bmw-prod/ec5351c9-d22b-4918-ad6c-1838064d3a64.json') - .then((res) => res.json()) - .then((data) => { - const layer = new LineLayer({ - autoFit: true, - }) - .source(data) - .size(100000) - .shape('wall') - .style({ - opacity: 0.4, - sourceColor: '#0DCCFF', - targetColor: 'rbga(255,255,255, 0)', - heightfixed: true, - }); - scene.addLayer(layer); + + const layer = new LineLayer({ + autoFit: true, + }) + .source(data) + .size(100000) + .shape('wall') + .style({ + opacity: 0.4, + sourceColor: '#0DCCFF', + targetColor: 'rbga(255,255,255, 0)', + heightfixed: true, }); -} + + scene.addLayer(layer); + + return scene; +}; diff --git a/examples/demos/mask/index.ts b/examples/demos/mask/index.ts index 4e6cb0d7c5d..2f5c32c2458 100644 --- a/examples/demos/mask/index.ts +++ b/examples/demos/mask/index.ts @@ -1,3 +1,3 @@ -export { MapRender as multi } from './multi'; -export { MapRender as raster_tile } from './raster_tile'; -export { MapRender as single } from './single'; +export { multi } from './multi'; +export { rasterTile } from './raster-tile'; +export { single } from './single'; diff --git a/examples/demos/mask/multi.ts b/examples/demos/mask/multi.ts index 4d0c7487283..04bf594a0e3 100644 --- a/examples/demos/mask/multi.ts +++ b/examples/demos/mask/multi.ts @@ -1,22 +1,7 @@ -import { PolygonLayer, RasterLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; +import { PolygonLayer, RasterLayer } from '@antv/l7'; import * as GeoTIFF from 'geotiff'; -import type { RenderDemoOptions } from '../../types'; - -async function getTiffData(url: string) { - const response = await fetch(url); - const arrayBuffer = await response.arrayBuffer(); - const tiff = await GeoTIFF.fromArrayBuffer(arrayBuffer); - const image = await tiff.getImage(); - const width = image.getWidth(); - const height = image.getHeight(); - const values = await image.readRasters(); - return { - data: values[0], - width, - height, - }; -} +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; const leftMaskGeoData = { type: 'FeatureCollection', @@ -40,87 +25,91 @@ const leftMaskGeoData = { ], }; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ +export const multi: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { style: 'light', center: [121.434765, 31.256735], zoom: 14.83, - }), + }, }); - scene.on('loaded', async () => { - const colors = [ - '#d73027', - '#f46d43', - '#fdae61', - '#fee08b', - '#d9ef8b', - '#a6d96a', - '#66bd63', - '#1a9850', - ]; - const aqi1 = await getTiffData( - 'https://static.sencdn.com/stargazer/tiffs/forecast_aqi/2024020200_2024020211.tiff', - ); + const aqi1 = await getTiffData( + 'https://static.sencdn.com/stargazer/tiffs/forecast_aqi/2024020200_2024020211.tiff', + ); - const json = await ( - await fetch( - 'https://gw.alipayobjects.com/os/basement_prod/d2e0e930-fd44-4fca-8872-c1037b0fee7b.json', - ) - ).json(); + const json = await ( + await fetch( + 'https://gw.alipayobjects.com/os/basement_prod/d2e0e930-fd44-4fca-8872-c1037b0fee7b.json', + ) + ).json(); - const polygonLayer = new PolygonLayer({ - visible: true, - name: 'china', - }) - .source(json) - .shape('fill') - .color('#f00') - .style({ opacity: 0.1 }); + const polygonLayer = new PolygonLayer({ + visible: true, + name: 'china', + }) + .source(json) + .shape('fill') + .color('#f00') + .style({ opacity: 0.1 }); - const maskLayer = new PolygonLayer({ - visible: false, - name: 'rect', - }) - .source(leftMaskGeoData) - .shape('fill') - .color('red') - .style({ - opacity: 0.1, - }); + const maskLayer = new PolygonLayer({ + visible: false, + name: 'rect', + }) + .source(leftMaskGeoData) + .shape('fill') + .color('red') + .style({ + opacity: 0.1, + }); - const leftLayer = new RasterLayer({ - autoFit: true, - maskLayers: [polygonLayer], - // maskLayers: [polygonLayer, maskLayer], + const leftLayer = new RasterLayer({ + autoFit: true, + maskLayers: [polygonLayer], + // maskLayers: [polygonLayer, maskLayer], + }) + .source(aqi1.data, { + parser: { + type: 'raster', + width: aqi1.width, + height: aqi1.height, + extent: [73, 17, 135.95, 53.95], + }, }) - .source(aqi1.data, { - parser: { - type: 'raster', - width: aqi1.width, - height: aqi1.height, - extent: [73, 17, 135.95, 53.95], - }, - }) - .style({ - clampLow: false, - clampHigh: false, - domain: [-0, 500], - opacity: 0.8, - rampColors: { - type: 'linear', - colors: ['#d7191c', '#fdae61', '#ffffbf', '#a6d96a'].reverse(), - positions: [0, 50, 100, 150, 300, 500], - }, - }); + .style({ + clampLow: false, + clampHigh: false, + domain: [-0, 500], + opacity: 0.8, + rampColors: { + type: 'linear', + colors: ['#d7191c', '#fdae61', '#ffffbf', '#a6d96a'].reverse(), + positions: [0, 50, 100, 150, 300, 500], + }, + }); - leftLayer.addMask(maskLayer); + leftLayer.addMask(maskLayer); - scene.addLayer(leftLayer); - scene.addLayer(polygonLayer); - scene.addLayer(maskLayer); - }); + scene.addLayer(leftLayer); + scene.addLayer(polygonLayer); + scene.addLayer(maskLayer); + + return scene; +}; + +async function getTiffData(url: string) { + const response = await fetch(url); + const arrayBuffer = await response.arrayBuffer(); + const tiff = await GeoTIFF.fromArrayBuffer(arrayBuffer); + const image = await tiff.getImage(); + const width = image.getWidth(); + const height = image.getHeight(); + const values = await image.readRasters(); + return { + data: values[0], + width, + height, + }; } diff --git a/examples/demos/mask/raster-tile.ts b/examples/demos/mask/raster-tile.ts new file mode 100644 index 00000000000..518c760b208 --- /dev/null +++ b/examples/demos/mask/raster-tile.ts @@ -0,0 +1,57 @@ +import { PolygonLayer, RasterLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const rasterTile: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [121.434765, 31.256735], + zoom: 14.83, + }, + }); + + const maskData = await fetch( + 'https://gw.alipayobjects.com/os/bmw-prod/fccd80c0-2611-49f9-9a9f-e2a4dd12226f.json', + ).then((res) => res.json()); + + const maskPolygon = new PolygonLayer({ + visible: false, // 隐藏maskPolygon + autoFit: true, + }) + .source(maskData) + .shape('fill') + .color('#f00') + .style({ + opacity: 0.5, + }); + const layer = new RasterLayer({ + maskLayers: [maskPolygon], + }) + .source( + 'https://tiles{1-3}.geovisearth.com/base/v1/terrain_rgb/{z}/{x}/{y}?format=png&tmsIds=w&token=b2a0cfc132cd60b61391b9dd63c15711eadb9b38a9943e3f98160d5710aef788', + { + parser: { + type: 'rasterTile', + dataType: 'terrainRGB', + tileSize: 256, + zoomOffset: 0, + }, + }, + ) + .style({ + clampLow: false, + clampHigh: false, + domain: [0, 7000], + rampColors: { + type: 'linear', + colors: ['#d73027', '#fc8d59', '#fee08b', '#d9ef8b', '#91cf60', '#1a9850'], + positions: [0, 200, 500, 1000, 2000, 7000], // '#1a9850' + }, + }); + + scene.addLayer(layer); + scene.addLayer(maskPolygon); + + return scene; +}; diff --git a/examples/demos/mask/raster_tile.ts b/examples/demos/mask/raster_tile.ts deleted file mode 100644 index 2b4388fe146..00000000000 --- a/examples/demos/mask/raster_tile.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { PolygonLayer, RasterLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; - -const colorList = [ - '#419bdf', // Water - - '#358221', // Tree - - '#88b053', // Grass - - '#7a87c6', // vegetation - - '#e49635', // Crops - - '#dfc35a', // shrub - - '#ED022A', // Built Area - - '#EDE9E4', // Bare ground - - '#F2FAFF', // Snow - - '#C8C8C8', // Clouds -]; -const positions = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; - -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', - center: [121.434765, 31.256735], - zoom: 14.83, - }), - }); - - scene.on('loaded', () => { - fetch('https://gw.alipayobjects.com/os/bmw-prod/fccd80c0-2611-49f9-9a9f-e2a4dd12226f.json') - .then((res) => res.json()) - .then((maskData) => { - const maskPolygon = new PolygonLayer({ - visible: false, // 隐藏maskPolygon - autoFit: true, - }) - .source(maskData) - .shape('fill') - .color('#f00') - .style({ - opacity: 0.5, - }); - const layer = new RasterLayer({ - maskLayers: [maskPolygon], - }) - .source( - 'https://tiles{1-3}.geovisearth.com/base/v1/terrain_rgb/{z}/{x}/{y}?format=png&tmsIds=w&token=b2a0cfc132cd60b61391b9dd63c15711eadb9b38a9943e3f98160d5710aef788', - { - parser: { - type: 'rasterTile', - dataType: 'terrainRGB', - tileSize: 256, - zoomOffset: 0, - }, - }, - ) - .style({ - clampLow: false, - clampHigh: false, - domain: [0, 7000], - rampColors: { - type: 'linear', - colors: ['#d73027', '#fc8d59', '#fee08b', '#d9ef8b', '#91cf60', '#1a9850'], - positions: [0, 200, 500, 1000, 2000, 7000], // '#1a9850' - }, - }); - - scene.addLayer(layer); - scene.addLayer(maskPolygon); - }); - }); -} diff --git a/examples/demos/mask/single.ts b/examples/demos/mask/single.ts index 6a818c3c66f..5f9dc5fff74 100644 --- a/examples/demos/mask/single.ts +++ b/examples/demos/mask/single.ts @@ -1,23 +1,17 @@ -import { PointLayer, PolygonLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { PointLayer, PolygonLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const single: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [120.165, 30.26], pitch: 0, zoom: 15, - }), + }, }); - scene.addImage( - '00', - 'https://gw.alipayobjects.com/zos/basement_prod/604b5e7f-309e-40db-b95b-4fac746c5153.svg', - ); const maskData = { type: 'FeatureCollection', features: [ @@ -40,70 +34,66 @@ export function MapRender(options: RenderDemoOptions) { ], }; - scene.on('loaded', () => { - const polygonLayer = new PolygonLayer() - .source(maskData) - .shape('fill') - .color('#f00') - .style({ opacity: 0.5 }); + const polygonLayer = new PolygonLayer() + .source(maskData) + .shape('fill') + .color('#f00') + .style({ opacity: 0.5 }); - const point1 = new PointLayer({ - zIndex: 1, - maskLayers: [polygonLayer], - }) - .source( - [ - { - name: 'n5', - lng: 120.17, - lat: 30.255, - }, - ], + const point1 = new PointLayer({ + zIndex: 1, + maskLayers: [polygonLayer], + }) + .source( + [ { - parser: { - type: 'json', - x: 'lng', - y: 'lat', - }, + name: 'n5', + lng: 120.17, + lat: 30.255, }, - ) - .shape('simple') - .size(30) - .style({ - opacity: 0.6, - }) - .active(true); - - const point2 = new PointLayer({ - maskLayers: [polygonLayer], + ], + { + parser: { + type: 'json', + x: 'lng', + y: 'lat', + }, + }, + ) + .shape('simple') + .size(30) + .style({ + opacity: 0.6, }) - .source( - [ - { - name: 'n4', - lng: 120.17, - lat: 30.2565, - }, - ], + .active(true); + + const point2 = new PointLayer({ + maskLayers: [polygonLayer], + }) + .source( + [ { - parser: { - type: 'json', - x: 'lng', - y: 'lat', - }, + name: 'n4', + lng: 120.17, + lat: 30.2565, + }, + ], + { + parser: { + type: 'json', + x: 'lng', + y: 'lat', }, - ) - .shape('simple') - .size(30) - .color('#0f0') - .active(true); + }, + ) + .shape('simple') + .size(30) + .color('#0f0') + .active(true); - scene.addLayer(point1); - scene.addLayer(polygonLayer); - scene.addLayer(point2); + scene.addLayer(point1); + scene.addLayer(polygonLayer); + scene.addLayer(point2); - if (window['screenshot']) { - window['screenshot'](); - } - }); -} + return scene; +}; diff --git a/examples/demos/point/billboard.ts b/examples/demos/point/billboard.ts index f3658c66cc3..dd5605a4099 100644 --- a/examples/demos/point/billboard.ts +++ b/examples/demos/point/billboard.ts @@ -1,18 +1,17 @@ -import { PointLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { PointLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const billboard: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [120.188193, 30.292542], pitch: 0, zoom: 16, - }), + }, }); + const layer = new PointLayer() .source({ type: 'FeatureCollection', @@ -71,11 +70,7 @@ export function MapRender(options: RenderDemoOptions) { .color('#f00') .shape('simple'); - scene.on('loaded', () => { - scene.addLayer(layer); + scene.addLayer(layer); - if (window['screenshot']) { - window['screenshot'](); - } - }); -} + return scene; +}; diff --git a/examples/demos/point/column.ts b/examples/demos/point/column.ts index 6f0ddaba6b3..3a8acd7965d 100644 --- a/examples/demos/point/column.ts +++ b/examples/demos/point/column.ts @@ -1,43 +1,38 @@ -import { PointLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { PointLayer } from '@antv/l7'; +import data from '../../data/shanghaixi-village.json'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ +export const column: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { style: 'light', center: [121.400257, 31.25287], zoom: 14.55, - rotation: 134.9507, - }), + pitch: 45, + }, }); - fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json') - .then((res) => res.json()) - .then((data) => { - const pointLayer = new PointLayer({}) - .source(data, { - parser: { - type: 'json', - x: 'longitude', - y: 'latitude', - }, - }) - .shape('name', ['cylinder', 'triangleColumn', 'hexagonColumn', 'squareColumn']) - .active(true) - .size('unit_price', (h) => { - return [6, 6, 100]; - }) - .color('name', ['#739DFF', '#61FCBF', '#FFDE74', '#FF896F']) - .style({ - opacity: 1, - }); - scene.addLayer(pointLayer); - - if (window['screenshot']) { - window['screenshot'](); - } + const pointLayer = new PointLayer({}) + .source(data, { + parser: { + type: 'json', + x: 'longitude', + y: 'latitude', + }, + }) + .shape('name', ['cylinder', 'triangleColumn', 'hexagonColumn', 'squareColumn']) + .active(true) + .size('unit_price', (h) => { + return [6, 6, 100]; + }) + .color('name', ['#739DFF', '#61FCBF', '#FFDE74', '#FF896F']) + .style({ + opacity: 1, }); -} + + scene.addLayer(pointLayer); + + return scene; +}; diff --git a/examples/demos/point/dot.ts b/examples/demos/point/dot.ts new file mode 100644 index 00000000000..c441d08a640 --- /dev/null +++ b/examples/demos/point/dot.ts @@ -0,0 +1,48 @@ +import { PointLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const dot: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [116.417463, 40.015175], + zoom: 8, + minZoom: 5, + }, + }); + + const data = await fetch( + 'https://gw.alipayobjects.com/os/antfincdn/8Ps2h%24qgmk/traffic_110000.csv', + ).then((res) => res.text()); + + const colors = ['#c57f34', '#cbfddf', '#edea70', '#8cc9f1', '#2c7bb6']; + const pointLayer = new PointLayer({}) + .source(data, { + parser: { + type: 'csv', + y: 'lat', + x: 'lng', + }, + }) + .shape('dot') + .size(0.5) + .color('type', (type) => { + switch (parseInt(type)) { + case 3: + return colors[0]; + case 4: + return colors[1]; + case 41: + return colors[2]; + case 5: + return colors[3]; + default: + return colors[4]; + } + }); + + scene.addLayer(pointLayer); + + return scene; +}; diff --git a/examples/demos/webgpu/point_image.ts b/examples/demos/point/fill-image.ts similarity index 62% rename from examples/demos/webgpu/point_image.ts rename to examples/demos/point/fill-image.ts index ace11447710..2e52f629add 100644 --- a/examples/demos/webgpu/point_image.ts +++ b/examples/demos/point/fill-image.ts @@ -1,20 +1,18 @@ -import { PointLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; +import { PointLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(option: { map: string; renderer: string }) { - const scene = new Scene({ - id: 'map', - renderer: option.renderer, - enableWebGPU: true, - shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', - map: new allMap[option.map || 'Map']({ - style: 'light', +export const fillImage: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [120, 30], - pitch: 60, + pitch: 0, zoom: 14, - }), + }, }); - scene.addImage( + + await scene.addImage( 'marker', 'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*BJ6cTpDcuLcAAAAAAAAAAABkARQnAQ', ); @@ -46,7 +44,7 @@ export function MapRender(option: { map: string; renderer: string }) { .source( [ { - lng: 120, + lng: 120.01, lat: 30, name: 'marker', }, @@ -66,8 +64,8 @@ export function MapRender(option: { map: string; renderer: string }) { rotation: 90, }); - scene.on('loaded', () => { - scene.addLayer(pointLayer); - scene.addLayer(pointLayer2); - }); -} + scene.addLayer(pointLayer); + scene.addLayer(pointLayer2); + + return scene; +}; diff --git a/examples/demos/point/fill.ts b/examples/demos/point/fill.ts index 3043ba8136d..4175a40132a 100644 --- a/examples/demos/point/fill.ts +++ b/examples/demos/point/fill.ts @@ -1,55 +1,52 @@ -import { PointLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { PointLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const fill: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [121.435159, 31.256971], zoom: 14.89, - minZoom: 10, - }), + }, }); - scene.on('loaded', () => { - fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json') - .then((res) => res.json()) - .then((data) => { - const pointLayer = new PointLayer({}) - .source(data, { - parser: { - type: 'json', - x: 'longitude', - y: 'latitude', - }, - }) - .shape('name', [ - 'circle', - 'triangle', - 'square', - 'pentagon', - 'hexagon', - 'octogon', - 'hexagram', - 'rhombus', - 'vesica', - ]) - .size('unit_price', [10, 25]) - .active(false) - .select(true) - .color('name', ['#5B8FF9', '#5CCEA1', '#5D7092', '#F6BD16', '#E86452']) - .style({ - opacity: 1, - strokeWidth: 2, - }); - scene.addLayer(pointLayer); + const data = await fetch( + 'https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json', + ).then((res) => res.json()); - if (window['screenshot']) { - window['screenshot'](); - } - }); - }); -} + const pointLayer = new PointLayer({}) + .source(data, { + parser: { + type: 'json', + x: 'longitude', + y: 'latitude', + }, + }) + .shape('name', [ + 'circle', + 'triangle', + 'square', + 'pentagon', + 'hexagon', + 'octogon', + 'hexagram', + 'rhombus', + 'vesica', + ]) + .size('unit_price', [10, 25]) + .active(false) + .select(true) + .color('name', ['#5B8FF9', '#5CCEA1', '#5D7092', '#F6BD16', '#E86452']) + .style({ + opacity: { + field: 'unit_price', + value: () => 1, + }, + strokeWidth: 2, + }); + + scene.addLayer(pointLayer); + + return scene; +}; diff --git a/examples/demos/point/fill_image.ts b/examples/demos/point/fill_image.ts deleted file mode 100644 index 8b8bdb5fe6a..00000000000 --- a/examples/demos/point/fill_image.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { PointLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; - -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', - center: [120, 30], - pitch: 60, - zoom: 14, - }), - }); - - scene.addImage( - 'marker', - 'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*BJ6cTpDcuLcAAAAAAAAAAABkARQnAQ', - ); - - const pointLayer = new PointLayer({ layerType: 'fillImage' }) - .source( - [ - { - lng: 120, - lat: 30, - name: 'marker', - }, - ], - { - parser: { - type: 'json', - x: 'lng', - y: 'lat', - }, - }, - ) - .style({ - unit: 'meter', - }) - .shape('marker') - .size(36); - - const pointLayer2 = new PointLayer({ layerType: 'fillImage' }) - .source( - [ - { - lng: 120, - lat: 30, - name: 'marker', - }, - ], - { - parser: { - type: 'json', - x: 'lng', - y: 'lat', - }, - }, - ) - .shape('marker') - .size(36) - .active(true) - .style({ - rotation: 90, - }); - - scene.on('loaded', () => { - scene.addLayer(pointLayer); - scene.addLayer(pointLayer2); - - if (window['screenshot']) { - window['screenshot'](); - } - }); -} diff --git a/examples/demos/point/image.ts b/examples/demos/point/image.ts index d159ae2b460..943d9203591 100644 --- a/examples/demos/point/image.ts +++ b/examples/demos/point/image.ts @@ -1,63 +1,47 @@ -import { PointLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { PointLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const image: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [121.434765, 31.256735], zoom: 14.83, - }), + }, }); - scene.addImage( - '00', - 'https://gw.alipayobjects.com/zos/basement_prod/604b5e7f-309e-40db-b95b-4fac746c5153.svg', - ); - scene.addImage( - '01', - 'https://gw.alipayobjects.com/zos/basement_prod/30580bc9-506f-4438-8c1a-744e082054ec.svg', - ); - scene.addImage( - '02', - 'https://gw.alipayobjects.com/zos/basement_prod/7aa1f460-9f9f-499f-afdf-13424aa26bbf.svg', - ); - scene.on('loaded', () => { - fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json') - .then((res) => res.json()) - .then((data) => { - const imageLayer = new PointLayer() - .source(data, { - parser: { - type: 'json', - x: 'longitude', - y: 'latitude', - }, - }) - .shape('name', ['00', '01', '02']) - .size(10); - const imageLayerText = new PointLayer() - .source(data, { - parser: { - type: 'json', - x: 'longitude', - y: 'latitude', - }, - }) - .shape('name', 'text') - .color('#f00') - .size(25) - .style({ - textOffset: [0, 20], - }); - scene.addLayer(imageLayer); - scene.addLayer(imageLayerText); - if (window['screenshot']) { - window['screenshot'](); - } - }); - }); -} + await Promise.all([ + scene.addImage( + '00', + 'https://gw.alipayobjects.com/zos/basement_prod/604b5e7f-309e-40db-b95b-4fac746c5153.svg', + ), + scene.addImage( + '01', + 'https://gw.alipayobjects.com/zos/basement_prod/30580bc9-506f-4438-8c1a-744e082054ec.svg', + ), + scene.addImage( + '02', + 'https://gw.alipayobjects.com/zos/basement_prod/7aa1f460-9f9f-499f-afdf-13424aa26bbf.svg', + ), + ]); + + const data = await fetch( + 'https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json', + ).then((res) => res.json()); + + const imageLayer = new PointLayer() + .source(data, { + parser: { + type: 'json', + x: 'longitude', + y: 'latitude', + }, + }) + .shape('name', ['00', '01', '02']) + .size(10); + + scene.addLayer(imageLayer); + + return scene; +}; diff --git a/examples/demos/point/index.ts b/examples/demos/point/index.ts index 3684a2fc28b..de3da78e235 100644 --- a/examples/demos/point/index.ts +++ b/examples/demos/point/index.ts @@ -1,6 +1,8 @@ -export { MapRender as billboard } from './billboard'; -export { MapRender as column } from './column'; -export { MapRender as fill } from './fill'; -export { MapRender as fill_image } from './fill_image'; -export { MapRender as image } from './image'; -export { MapRender as text } from './text'; +export { billboard } from './billboard'; +export { column } from './column'; +export { dot } from './dot'; +export { fill } from './fill'; +export { fillImage } from './fill-image'; +export { image } from './image'; +export { radar } from './radar'; +export { text } from './text'; diff --git a/examples/demos/point/radar.ts b/examples/demos/point/radar.ts new file mode 100644 index 00000000000..354240d22c3 --- /dev/null +++ b/examples/demos/point/radar.ts @@ -0,0 +1,29 @@ +import { PointLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const radar: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [120, 30], + zoom: 13, + }, + }); + + const layer = new PointLayer() + .source([{ lng: 120, lat: 30 }], { + parser: { type: 'json', x: 'lng', y: 'lat' }, + }) + .shape('radar') + .size(100) + .color('#d00') + .style({ + speed: 5, + }) + .animate(true); + + scene.addLayer(layer); + + return scene; +}; diff --git a/examples/demos/point/text.ts b/examples/demos/point/text.ts index c80b76263a1..bacb92e54ae 100644 --- a/examples/demos/point/text.ts +++ b/examples/demos/point/text.ts @@ -1,40 +1,36 @@ -import { PointLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { PointLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const text: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [121.434765, 31.256735], zoom: 14.83, - }), + }, }); - scene.on('loaded', () => { - fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json') - .then((res) => res.json()) - .then((data) => { - const imageLayerText = new PointLayer() - .source(data, { - parser: { - type: 'json', - x: 'longitude', - y: 'latitude', - }, - }) - .shape('name', 'text') - .color('#f00') - .size(25) - .style({ - textOffset: [0, 20], - }); - scene.addLayer(imageLayerText); - if (window['screenshot']) { - window['screenshot'](); - } - }); - }); -} + const data = await fetch( + 'https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json', + ).then((res) => res.json()); + + const imageLayerText = new PointLayer() + .source(data, { + parser: { + type: 'json', + x: 'longitude', + y: 'latitude', + }, + }) + .shape('name', 'text') + .color('#f00') + .size(25) + .style({ + textOffset: [0, 20], + }); + + scene.addLayer(imageLayerText); + + return scene; +}; diff --git a/examples/demos/polygon/extrude-city.ts b/examples/demos/polygon/extrude-city.ts new file mode 100644 index 00000000000..337f0b962d0 --- /dev/null +++ b/examples/demos/polygon/extrude-city.ts @@ -0,0 +1,28 @@ +import { PolygonLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const extrudeCity: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + style: 'dark', + center: [121.434765, 31.256735], + zoom: 14.83, + pitch: 45, + }, + }); + + const data = await fetch( + 'https://gw.alipayobjects.com/os/basement_prod/972566c5-a2b9-4a7e-8da1-bae9d0eb0117.json', + ).then((res) => res.json()); + + const layer = new PolygonLayer({ autoFit: true }) + .source(data) + .shape('extrude') + .size('h20', [100, 120, 160, 200, 260, 500]) + .color('h20', ['#816CAD', '#A67FB5', '#C997C7', '#DEB8D4', '#F5D4E6', '#FAE4F1', '#FFF3FC']); + scene.addLayer(layer); + + return scene; +}; diff --git a/examples/demos/polygon/extrude.ts b/examples/demos/polygon/extrude.ts index 8bd0a69673f..6263afe0317 100644 --- a/examples/demos/polygon/extrude.ts +++ b/examples/demos/polygon/extrude.ts @@ -1,57 +1,33 @@ -import { PolygonLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { PolygonLayer } from '@antv/l7'; +import data from '../../data/nanjing-city.json'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const extrude: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [121.434765, 31.256735], zoom: 14.83, - }), + pitch: 45, + }, }); - const colors = [ - '#87CEFA', - '#00BFFF', + const filllayer = new PolygonLayer({ + name: 'fill', + zIndex: 3, + autoFit: true, + }) + .source(data) + .shape('extrude') + .active(true) + .size('unit_price', (unit_price) => unit_price) + .color('count', ['#f2f0f7', '#dadaeb', '#bcbddc', '#9e9ac8', '#756bb1', '#54278f']) + .style({ + pickLight: true, + opacity: 1, + }); + scene.addLayer(filllayer); - '#7FFFAA', - '#00FF7F', - '#32CD32', - - '#F0E68C', - '#FFD700', - - '#FF7F50', - '#FF6347', - '#FF0000', - ]; - scene.on('loaded', () => { - fetch('https://gw.alipayobjects.com/os/bmw-prod/94763191-2816-4c1a-8d0d-8bcf4181056a.json') - .then((res) => res.json()) - .then((data) => { - const filllayer = new PolygonLayer({ - name: 'fill', - zIndex: 3, - autoFit: true, - }) - .source(data) - .shape('extrude') - .active(true) - .size('unit_price', (unit_price) => unit_price) - .color('count', ['#f2f0f7', '#dadaeb', '#bcbddc', '#9e9ac8', '#756bb1', '#54278f']) - .style({ - pickLight: true, - - opacity: 1, - }); - scene.addLayer(filllayer); - - if (window['screenshot']) { - window['screenshot'](); - } - }); - }); -} + return scene; +}; diff --git a/examples/demos/polygon/extrusion.ts b/examples/demos/polygon/extrusion.ts new file mode 100644 index 00000000000..dca7e028622 --- /dev/null +++ b/examples/demos/polygon/extrusion.ts @@ -0,0 +1,32 @@ +import { PolygonLayer } from '@antv/l7'; +import data from '../../data/indoor-3d-map.json'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const extrusion: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [120, 29.732983], + zoom: 6.2, + pitch: 30, + }, + }); + + const provincelayerSide = new PolygonLayer({ + autoFit: true, + }) + .source(data) + .size('height') + .shape('extrusion') + .color('color') + .style({ + extrusionBase: { + field: 'base_height', + }, + opacity: 1.0, + }); + scene.addLayer(provincelayerSide); + + return scene; +}; diff --git a/examples/demos/polygon/fill-linear.ts b/examples/demos/polygon/fill-linear.ts new file mode 100644 index 00000000000..60aeca101b1 --- /dev/null +++ b/examples/demos/polygon/fill-linear.ts @@ -0,0 +1,56 @@ +import { PolygonLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const fillLinear: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [121.434765, 31.256735], + zoom: 14.83, + }, + }); + + const data = { + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + properties: { + testOpacity: 0.8, + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [113.8623046875, 30.031055426540206], + [116.3232421875, 30.031055426540206], + [116.3232421875, 31.090574094954192], + [113.8623046875, 31.090574094954192], + [113.8623046875, 30.031055426540206], + ], + ], + }, + }, + ], + }; + + const layer = new PolygonLayer({ + autoFit: true, + }) + .source(data) + .shape('fill') + .color('red') + .active(true) + .style({ + opacity: 0.5, + opacityLinear: { + enable: true, + dir: 'in', + }, + }); + + scene.addLayer(layer); + + return scene; +}; diff --git a/examples/demos/polygon/fill.ts b/examples/demos/polygon/fill.ts index 44f7d99db1a..8da1cf94ded 100644 --- a/examples/demos/polygon/fill.ts +++ b/examples/demos/polygon/fill.ts @@ -1,61 +1,37 @@ -import { PolygonLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { PolygonLayer } from '@antv/l7'; +import data from '../../data/us-states.json'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', - center: [121.434765, 31.256735], - zoom: 14.83, - }), +export const fill: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [-96, 37.8], + zoom: 3, + }, }); - const data = { - type: 'FeatureCollection', - features: [ - { - type: 'Feature', - properties: { - testOpacity: 0.8, - }, - geometry: { - type: 'Polygon', - coordinates: [ - [ - [113.8623046875, 30.031055426540206], - [116.3232421875, 30.031055426540206], - [116.3232421875, 31.090574094954192], - [113.8623046875, 31.090574094954192], - [113.8623046875, 30.031055426540206], - ], - ], - }, - }, - ], - }; - - const layer = new PolygonLayer({ - autoFit: true, - }) + const color = [ + 'rgb(255,255,217)', + 'rgb(237,248,177)', + 'rgb(199,233,180)', + 'rgb(127,205,187)', + 'rgb(65,182,196)', + 'rgb(29,145,192)', + 'rgb(34,94,168)', + 'rgb(12,44,132)', + ]; + const layer = new PolygonLayer({}) .source(data) + .scale('density', { + type: 'quantile', + }) + .color('density', color) .shape('fill') - .color('red') - .active(true) - .style({ - opacity: 0.5, - opacityLinear: { - enable: true, - dir: 'in', - }, - }); + .active(true); - scene.on('loaded', () => { - scene.addLayer(layer); - if (window['screenshot']) { - window['screenshot'](); - } - }); -} + scene.addLayer(layer); + + return scene; +}; diff --git a/examples/demos/polygon/index.ts b/examples/demos/polygon/index.ts index acecf274f9e..295b172e10c 100644 --- a/examples/demos/polygon/index.ts +++ b/examples/demos/polygon/index.ts @@ -1,5 +1,8 @@ -export { MapRender as extrude } from './extrude'; -export { MapRender as fill } from './fill'; -export { MapRender as ocean } from './ocean'; -export { MapRender as texture } from './texture'; -export { MapRender as water } from './water'; +export { extrude } from './extrude'; +export { extrudeCity } from './extrude-city'; +export { extrusion } from './extrusion'; +export { fill } from './fill'; +export { fillLinear } from './fill-linear'; +export { ocean } from './ocean'; +export { texture } from './texture'; +export { water } from './water'; diff --git a/examples/demos/polygon/ocean.ts b/examples/demos/polygon/ocean.ts index b277f4717d7..bf6043fc8f7 100644 --- a/examples/demos/polygon/ocean.ts +++ b/examples/demos/polygon/ocean.ts @@ -1,16 +1,14 @@ -import { PolygonLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { PolygonLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const ocean: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [121.434765, 31.256735], zoom: 14.83, - }), + }, }); const layer = new PolygonLayer({ @@ -43,11 +41,7 @@ export function MapRender(options: RenderDemoOptions) { watercolor: '#6D99A8', }); - scene.on('loaded', () => { - scene.addLayer(layer); + scene.addLayer(layer); - if (window['screenshot']) { - window['screenshot'](); - } - }); -} + return scene; +}; diff --git a/examples/demos/polygon/texture.ts b/examples/demos/polygon/texture.ts index 6c45d31052f..5dd0b0d7737 100644 --- a/examples/demos/polygon/texture.ts +++ b/examples/demos/polygon/texture.ts @@ -1,48 +1,43 @@ -import { PolygonLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { PolygonLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const texture: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [121.434765, 31.256735], zoom: 14.83, - }), + }, }); - scene.on('loaded', () => { - fetch('https://geo.datav.aliyun.com/areas_v3/bound/330000.json') - .then((res) => res.json()) - .then((data) => { - const provincelayerTop = new PolygonLayer({ - autoFit: true, - }) - .source(data) - .size(1000) - .shape('extrude') - .size(10000) - .color('#0DCCFF') - // .active({ - // color: 'rgb(100,230,255)', - // }) - .style({ - heightfixed: true, - // pickLight: true, - mapTexture: - 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*bm0eRKOCcNoAAAAAAAAAAAAADmJ7AQ/original', - // mapTexture:'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*3UcORbAv_zEAAAAAAAAAAAAADmJ7AQ/original', - // raisingHeight: 10000, - opacity: 0.8, - // sidesurface: false, - }); - scene.addLayer(provincelayerTop); + const data = await fetch('https://geo.datav.aliyun.com/areas_v3/bound/330000.json').then((res) => + res.json(), + ); - if (window['screenshot']) { - window['screenshot'](); - } - }); - }); -} + const provincelayerTop = new PolygonLayer({ + autoFit: true, + }) + .source(data) + .size(1000) + .shape('extrude') + .size(10000) + .color('#0DCCFF') + // .active({ + // color: 'rgb(100,230,255)', + // }) + .style({ + heightfixed: true, + // pickLight: true, + mapTexture: + 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*bm0eRKOCcNoAAAAAAAAAAAAADmJ7AQ/original', + // mapTexture:'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*3UcORbAv_zEAAAAAAAAAAAAADmJ7AQ/original', + // raisingHeight: 10000, + opacity: 0.8, + // sidesurface: false, + }); + + scene.addLayer(provincelayerTop); + + return scene; +}; diff --git a/examples/demos/polygon/water.ts b/examples/demos/polygon/water.ts index 01c86e28ff6..1b58c9124f9 100644 --- a/examples/demos/polygon/water.ts +++ b/examples/demos/polygon/water.ts @@ -1,16 +1,14 @@ -import { PolygonLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { PolygonLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const water: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [121.434765, 31.256735], zoom: 14.83, - }), + }, }); const layer = new PolygonLayer({ @@ -46,11 +44,7 @@ export function MapRender(options: RenderDemoOptions) { }) .animate(true); - scene.on('loaded', () => { - scene.addLayer(layer); + scene.addLayer(layer); - if (window['screenshot']) { - window['screenshot'](); - } - }); -} + return scene; +}; diff --git a/examples/demos/raster/dem.ts b/examples/demos/raster/dem.ts index d2ad6e0b702..0883046d2c1 100644 --- a/examples/demos/raster/dem.ts +++ b/examples/demos/raster/dem.ts @@ -1,73 +1,69 @@ -import { RasterLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; +import { RasterLayer } from '@antv/l7'; import * as GeoTIFF from 'geotiff'; -import type { RenderDemoOptions } from '../../types'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const dem: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [121.434765, 31.256735], zoom: 3, - }), + }, }); - async function getTiffData() { - const response = await fetch( - 'https://gw.alipayobjects.com/os/rmsportal/XKgkjjGaAzRyKupCBiYW.dat', - ); - const arrayBuffer = await response.arrayBuffer(); - return arrayBuffer; - } - scene.on('loaded', async () => { - const tiffdata = await getTiffData(); - const tiff = await GeoTIFF.fromArrayBuffer(tiffdata); - const image = await tiff.getImage(); - const width = image.getWidth(); - const height = image.getHeight(); - const values = await image.readRasters(); - const layer = new RasterLayer(); - layer - .source(values[0], { - parser: { - type: 'raster', - width, - height, - extent: [73.482190241, 3.82501784112, 135.106618732, 57.6300459963], - }, - }) - .style({ - opacity: 1, - // clampLow: false, - // clampHigh: false, - domain: [0, 10000], - rampColors: { - type: 'custom', - colors: [ - '#b2182b', - '#d6604d', - '#f4a582', - '#fddbc7', - '#f7f7f7', - '#d1e5f0', - '#92c5de', - '#4393c3', - '#2166ac', - ], - positions: [0, 50, 200, 500, 2000, 3000, 4000, 5000, 8000, 10000], - }, - }); + const tiffdata = await getTiffData(); + const tiff = await GeoTIFF.fromArrayBuffer(tiffdata); + const image = await tiff.getImage(); + const width = image.getWidth(); + const height = image.getHeight(); + const values = await image.readRasters(); - layer.on('inited', () => { - console.log(layer.getLegend('color')); + const layer = new RasterLayer(); + layer + .source(values[0], { + parser: { + type: 'raster', + width, + height, + extent: [73.482190241, 3.82501784112, 135.106618732, 57.6300459963], + }, + }) + .style({ + opacity: 1, + // clampLow: false, + // clampHigh: false, + domain: [0, 10000], + rampColors: { + type: 'custom', + colors: [ + '#b2182b', + '#d6604d', + '#f4a582', + '#fddbc7', + '#f7f7f7', + '#d1e5f0', + '#92c5de', + '#4393c3', + '#2166ac', + ], + positions: [0, 50, 200, 500, 2000, 3000, 4000, 5000, 8000, 10000], + }, }); - scene.addLayer(layer); - - if (window['screenshot']) { - window['screenshot'](); - } + layer.on('inited', () => { + console.log(layer.getLegend('color')); }); + + scene.addLayer(layer); + + return scene; +}; + +async function getTiffData() { + const response = await fetch( + 'https://gw.alipayobjects.com/os/rmsportal/XKgkjjGaAzRyKupCBiYW.dat', + ); + const arrayBuffer = await response.arrayBuffer(); + return arrayBuffer; } diff --git a/examples/demos/raster/image.ts b/examples/demos/raster/image.ts index f6a6a1cf473..2668517844a 100644 --- a/examples/demos/raster/image.ts +++ b/examples/demos/raster/image.ts @@ -1,31 +1,27 @@ -import { ImageLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { ImageLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const image: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [115.5268, 34.3628], zoom: 7, - }), + }, }); - scene.on('loaded', () => { - const layer = new ImageLayer({}); - layer.source( - 'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*8SUaRr7bxNsAAAAAAAAAAABkARQnAQ', - { - parser: { - type: 'image', - extent: [113.1277263548, 32.3464238863, 118.1365790452, 36.4786759137], - }, + + const layer = new ImageLayer({}); + layer.source( + 'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*8SUaRr7bxNsAAAAAAAAAAABkARQnAQ', + { + parser: { + type: 'image', + extent: [113.1277263548, 32.3464238863, 118.1365790452, 36.4786759137], }, - ); - scene.addLayer(layer); - if (window['screenshot']) { - window['screenshot'](); - } - }); -} + }, + ); + scene.addLayer(layer); + + return scene; +}; diff --git a/examples/demos/raster/imageBox.ts b/examples/demos/raster/imageBox.ts new file mode 100644 index 00000000000..c0ef659a2bc --- /dev/null +++ b/examples/demos/raster/imageBox.ts @@ -0,0 +1,35 @@ +import { ImageLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const imageBox: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [115.5268, 34.3628], + zoom: 7, + }, + }); + + const layer = new ImageLayer({ + autoFit: true, + }); + layer.source( + 'https://mdn.alipayobjects.com/huamei_gjo0cl/afts/img/A*vm_9S64uA0UAAAAAAAAAAAAADjDHAQ/original', + + { + parser: { + type: 'image', + coordinates: [ + [100.959388, 41.619522], + [101.229887, 41.572654], + [101.16971, 41.377836], + [100.900015, 41.424628], + ], + }, + }, + ); + scene.addLayer(layer); + + return scene; +}; diff --git a/examples/demos/raster/image_coord.ts b/examples/demos/raster/image_coord.ts deleted file mode 100644 index 37ca975dd5b..00000000000 --- a/examples/demos/raster/image_coord.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { ImageLayer, PolygonLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; - -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', - center: [115.5268, 34.3628], - zoom: 7, - }), - }); - scene.on('loaded', () => { - const fill = new PolygonLayer() - .source({ - type: 'FeatureCollection', - features: [ - { - type: 'Feature', - properties: {}, - geometry: { - type: 'Polygon', - coordinates: [ - [ - [-80.425, 46.437], - [-71.516, 46.437], - [-71.516, 37.936], - [-80.425, 37.936], - [-80.425, 46.437], - ], - ], - }, - }, - ], - }) - .shape('line') - .color('red') - .size(1) - .style({ opacity: 1 }); - const layer = new ImageLayer({ - autoFit: true, - }); - layer.source( - 'https://mdn.alipayobjects.com/huamei_gjo0cl/afts/img/A*vm_9S64uA0UAAAAAAAAAAAAADjDHAQ/original', - - { - parser: { - type: 'image', - coordinates: [ - [100.959388, 41.619522], - [101.229887, 41.572654], - [101.16971, 41.377836], - [100.900015, 41.424628], - ], - }, - }, - ); - scene.addLayer(layer); - scene.addLayer(fill); - if (window['screenshot']) { - window['screenshot'](); - } - }); -} diff --git a/examples/demos/raster/index.ts b/examples/demos/raster/index.ts index bb806fff334..f286416f5d8 100644 --- a/examples/demos/raster/index.ts +++ b/examples/demos/raster/index.ts @@ -1,6 +1,6 @@ -export { MapRender as dem } from './dem'; -export { MapRender as image } from './image'; -export { MapRender as image_box } from './image_coord'; -export { MapRender as multiband } from './multiband'; -export { MapRender as ndvi } from './ndvi'; -export { MapRender as tiff } from './tiff'; +export { dem } from './dem'; +export { image } from './image'; +export { imageBox } from './imageBox'; +export { multiband } from './multiband'; +export { ndvi } from './ndvi'; +export { tiff } from './tiff'; diff --git a/examples/demos/raster/multiband.ts b/examples/demos/raster/multiband.ts index ec8f4158d0a..6def2eac229 100644 --- a/examples/demos/raster/multiband.ts +++ b/examples/demos/raster/multiband.ts @@ -1,50 +1,43 @@ -import { RasterLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; +import { RasterLayer } from '@antv/l7'; import * as GeoTIFF from 'geotiff'; -import type { RenderDemoOptions } from '../../types'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -async function getTiffData(url: string) { - const response = await fetch(url); - const arrayBuffer = await response.arrayBuffer(); - return arrayBuffer; -} - -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ +export const multiband: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [130.5, 47], zoom: 10.5, - }), - }); - scene.on('loaded', () => { - addLayer(); + }, }); - async function addLayer() { - const url1 = 'https://gw.alipayobjects.com/zos/raptor/1667832825992/LC08_3857_clip_2.tif'; - const tiffdata = await getTiffData(url1); - const layer = new RasterLayer({ zIndex: 10 }); - const tiff = await GeoTIFF.fromArrayBuffer(tiffdata); - const image1 = await tiff.getImage(); - const value = await image1.readRasters(); - layer - .source(value, { - parser: { - type: 'rgb', - width: value.width, - height: value.height, - bands: [5, 4, 3], - extent: [130.39565357746957, 46.905730725742366, 130.73364094187343, 47.10217234153133], - }, - }) - .style({ - opacity: 1, - }); - scene.addLayer(layer); - if (window['screenshot']) { - window['screenshot'](); - } - } + const url1 = 'https://gw.alipayobjects.com/zos/raptor/1667832825992/LC08_3857_clip_2.tif'; + const tiffdata = await getTiffData(url1); + const layer = new RasterLayer({ zIndex: 10 }); + const tiff = await GeoTIFF.fromArrayBuffer(tiffdata); + const image1 = await tiff.getImage(); + const value = await image1.readRasters(); + layer + .source(value, { + parser: { + type: 'rgb', + width: value.width, + height: value.height, + bands: [5, 4, 3], + extent: [130.39565357746957, 46.905730725742366, 130.73364094187343, 47.10217234153133], + }, + }) + .style({ + opacity: 1, + }); + scene.addLayer(layer); + + return scene; +}; + +async function getTiffData(url: string) { + const response = await fetch(url); + const arrayBuffer = await response.arrayBuffer(); + return arrayBuffer; } diff --git a/examples/demos/raster/ndvi.ts b/examples/demos/raster/ndvi.ts index c4615a95206..397b05a5125 100644 --- a/examples/demos/raster/ndvi.ts +++ b/examples/demos/raster/ndvi.ts @@ -1,54 +1,48 @@ -import { RasterLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; +import { RasterLayer } from '@antv/l7'; import * as GeoTIFF from 'geotiff'; -import type { RenderDemoOptions } from '../../types'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -async function getTiffData(url: string) { - const response = await fetch(url); - const arrayBuffer = await response.arrayBuffer(); - return arrayBuffer; -} - -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ +export const ndvi: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [130.5, 47], zoom: 10.5, - }), - }); - scene.on('loaded', () => { - addLayer(); + }, }); - async function addLayer() { - const url1 = 'https://gw.alipayobjects.com/zos/raptor/1667832825992/LC08_3857_clip_2.tif'; - const tiffdata = await getTiffData(url1); - const layer = new RasterLayer({ zIndex: 10 }); - const tiff = await GeoTIFF.fromArrayBuffer(tiffdata); - const image1 = await tiff.getImage(); - const value = await image1.readRasters(); - layer - .source(value, { - parser: { - type: 'ndi', - width: value.width, - height: value.height, - bands: [3, 4], // 4 为 Band5是近红外(NIR)波段,3 为Band4是红光波段 - extent: [130.39565357746957, 46.905730725742366, 130.73364094187343, 47.10217234153133], - }, - }) - .style({ - domain: [-0.3, 0.5], - rampColors: { - colors: ['#ce4a2e', '#f0a875', '#fff8ba', '#bddd8a', '#5da73e', '#235117'], - positions: [0, 0.2, 0.4, 0.6, 0.8, 1.0], - }, - }); - scene.addLayer(layer); - if (window['screenshot']) { - window['screenshot'](); - } - } + const url1 = 'https://gw.alipayobjects.com/zos/raptor/1667832825992/LC08_3857_clip_2.tif'; + const tiffdata = await getTiffData(url1); + const layer = new RasterLayer({ zIndex: 10 }); + const tiff = await GeoTIFF.fromArrayBuffer(tiffdata); + const image1 = await tiff.getImage(); + const value = await image1.readRasters(); + layer + .source(value, { + parser: { + type: 'ndi', + width: value.width, + height: value.height, + bands: [3, 4], // 4 为 Band5是近红外(NIR)波段,3 为Band4是红光波段 + extent: [130.39565357746957, 46.905730725742366, 130.73364094187343, 47.10217234153133], + }, + }) + .style({ + domain: [-0.3, 0.5], + rampColors: { + colors: ['#ce4a2e', '#f0a875', '#fff8ba', '#bddd8a', '#5da73e', '#235117'], + positions: [0, 0.2, 0.4, 0.6, 0.8, 1.0], + }, + }); + + scene.addLayer(layer); + + return scene; +}; + +async function getTiffData(url: string) { + const response = await fetch(url); + const arrayBuffer = await response.arrayBuffer(); + return arrayBuffer; } diff --git a/examples/demos/raster/tiff.ts b/examples/demos/raster/tiff.ts index 3a3836f923e..2e896a731b0 100644 --- a/examples/demos/raster/tiff.ts +++ b/examples/demos/raster/tiff.ts @@ -1,7 +1,56 @@ -import { RasterLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; +import { RasterLayer } from '@antv/l7'; import * as GeoTIFF from 'geotiff'; -import type { RenderDemoOptions } from '../../types'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const tiff: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [105, 37.5], + zoom: 2.5, + }, + }); + + const tiffdata = await getTiffData(); + + const layer = new RasterLayer({ + zIndex: 2, + visible: true, + }); + layer + .source(tiffdata.data, { + parser: { + type: 'raster', + width: tiffdata.width, + height: tiffdata.height, + extent: [ + 73.4821902409999979, 3.8150178409999995, 135.1066187319999869, 57.6300459959999998, + ], + }, + }) + .style({ + clampLow: false, + clampHigh: false, + domain: [0, 90], + nodataValue: 0, + rampColors: { + colors: [ + 'rgba(92,58,16,0)', + 'rgba(92,58,16,0)', + '#fabd08', + '#f1e93f', + '#f1ff8f', + '#fcfff7', + ], + positions: [0, 0.05, 0.1, 0.25, 0.5, 1.0], + }, + }); + + scene.addLayer(layer); + + return scene; +}; async function getTiffData() { const response = await fetch( @@ -19,59 +68,3 @@ async function getTiffData() { height, }; } - -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - center: [105, 37.5], - zoom: 2.5, - }), - }); - scene.on('loaded', () => { - addLayer(); - // scene.setBgColor('#aaa') - }); - - async function addLayer() { - const tiffdata = await getTiffData(); - - const layer = new RasterLayer({ - zIndex: 2, - visible: true, - }); - layer - .source(tiffdata.data, { - parser: { - type: 'raster', - width: tiffdata.width, - height: tiffdata.height, - extent: [ - 73.4821902409999979, 3.8150178409999995, 135.1066187319999869, 57.6300459959999998, - ], - }, - }) - .style({ - clampLow: false, - clampHigh: false, - domain: [0, 90], - nodataValue: 0, - rampColors: { - colors: [ - 'rgba(92,58,16,0)', - 'rgba(92,58,16,0)', - '#fabd08', - '#f1e93f', - '#f1ff8f', - '#fcfff7', - ], - positions: [0, 0.05, 0.1, 0.25, 0.5, 1.0], - }, - }); - scene.addLayer(layer); - if (window['screenshot']) { - window['screenshot'](); - } - } -} diff --git a/examples/demos/template.ts b/examples/demos/template.ts deleted file mode 100644 index 4b47bc4e0d7..00000000000 --- a/examples/demos/template.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../types'; - -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', - center: [121.434765, 31.256735], - zoom: 14.83, - }), - }); -} diff --git a/examples/demos/tile/index.ts b/examples/demos/tile/index.ts index e357ba2facf..9732aa73181 100644 --- a/examples/demos/tile/index.ts +++ b/examples/demos/tile/index.ts @@ -1,6 +1,6 @@ -export { MapRender as image } from './normal'; -export { MapRender as perf } from './perf'; -export { MapRender as rgb } from './rgb'; -export { MapRender as usa } from './usa'; -export { MapRender as vector } from './vector'; -export { MapRender as worldline } from './world'; +export { rasterTile } from './raster-tile'; +export { terrainRGB } from './terrain-rgb'; +export { vectorCity } from './vector-city'; +export { vectorLine } from './vector-line'; +export { vectorPerf } from './vector-perf'; +export { vectorUSA } from './vector-usa'; diff --git a/examples/demos/tile/perf.ts b/examples/demos/tile/perf.ts deleted file mode 100644 index 901386b27c0..00000000000 --- a/examples/demos/tile/perf.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { LineLayer, PolygonLayer, Scene, Source } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; - -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - zoom: 4.5, - center: [116.412427, 39.303573], - }), - }); - - const url = - 'https://mvt.amap.com/district/CHN3/{z}/{x}/{y}/4096?key=309f07ac6bc48160e80b480ae511e1e9&version='; - const source = new Source(url, { - parser: { - type: 'mvt', - tileSize: 256, - warp: false, - }, - }); - - scene.on('loaded', () => { - const colors = {}; - const getColorByAdcode = function (adcode) { - if (!colors[adcode]) { - const gb = Math.floor(Math.random() * 155 + 50); - colors[adcode] = 'rgb(' + gb + ',' + gb + ',255)'; - } - - return colors[adcode]; - }; - // 绿地 - const fill = new PolygonLayer({ - sourceLayer: 'CHN_Districts', - featureId: 'adcode', - }) - .source(source) - .shape('fill') - // .color('#f00'); - .color('adcode', getColorByAdcode); - - fill.on('click', (e) => { - console.log(e); - }); - - const line = new LineLayer({ - sourceLayer: 'CHN_Districts_L', - }) - .source(source) - .shape('simple') - .color('#fee0d2'); - - const line2 = new LineLayer({ - sourceLayer: 'CHN_Citys_L', - }) - .source(source) - .shape('line') - .size(0.6) - .color('#fc9272'); - - const line3 = new LineLayer({ - sourceLayer: 'CHN_Provinces_L', - }) - .source(source) - .shape('line') - .size(0.6) - .color('#de2d26'); - - scene.addLayer(fill); - // scene.addLayer(line); - // scene.addLayer(line2); - // scene.addLayer(line3); - // scene.addLayer(line2); - // const debugerLayer = new TileDebugLayer({ usage: 'basemap' }); - // scene.addLayer(debugerLayer); - }); -} diff --git a/examples/demos/tile/normal.ts b/examples/demos/tile/raster-tile.ts similarity index 53% rename from examples/demos/tile/normal.ts rename to examples/demos/tile/raster-tile.ts index 763bb1ca0dc..d6ebf3f3ea0 100644 --- a/examples/demos/tile/normal.ts +++ b/examples/demos/tile/raster-tile.ts @@ -1,23 +1,21 @@ -import { RasterLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; +import { RasterLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const rasterTile: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [121.434765, 31.256735], zoom: 4.83, - }), + }, }); const url1 = 'https://tiles{1-3}.geovisearth.com/base/v1/ter/{z}/{x}/{y}?format=webp&tmsIds=w&token=b2a0cfc132cd60b61391b9dd63c15711eadb9b38a9943e3f98160d5710aef788'; const url2 = 'https://tiles{1-3}.geovisearth.com/base/v1/cat/{z}/{x}/{y}?format=png&tmsIds=w&token=b2a0cfc132cd60b61391b9dd63c15711eadb9b38a9943e3f98160d5710aef788'; - const layer1 = new RasterLayer({ + const layer = new RasterLayer({ zIndex: 1, }).source(url1, { parser: { @@ -27,8 +25,7 @@ export function MapRender(options: RenderDemoOptions) { }, }); - scene.on('loaded', () => { - scene.addLayer(layer1); - // scene.startAnimate() - }); -} + scene.addLayer(layer); + + return scene; +}; diff --git a/examples/demos/tile/rgb.ts b/examples/demos/tile/rgb.ts deleted file mode 100644 index 0e276c10e4b..00000000000 --- a/examples/demos/tile/rgb.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { RasterLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import type { RenderDemoOptions } from '../../types'; - -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', - center: [121.434765, 31.256735], - zoom: 4, - }), - }); - - scene.on('loaded', () => { - const layer = new RasterLayer() - .source( - 'https://tiles{1-3}.geovisearth.com/base/v1/terrain_rgb/{z}/{x}/{y}?format=png&tmsIds=w&token=b2a0cfc132cd60b61391b9dd63c15711eadb9b38a9943e3f98160d5710aef788', - { - parser: { - type: 'rasterTile', - dataType: 'terrainRGB', - tileSize: 256, - zoomOffset: 0, - }, - }, - ) - .style({ - clampLow: false, - clampHigh: false, - domain: [0, 7000], - rampColors: { - type: 'linear', - colors: ['#d73027', '#fc8d59', '#fee08b', '#d9ef8b', '#91cf60', '#1a9850'], - positions: [0, 200, 500, 1000, 2000, 7000], // '#1a9850' - }, - }); - scene.addLayer(layer); - }); -} diff --git a/examples/demos/tile/terrain-rgb.ts b/examples/demos/tile/terrain-rgb.ts new file mode 100644 index 00000000000..a794daa8396 --- /dev/null +++ b/examples/demos/tile/terrain-rgb.ts @@ -0,0 +1,40 @@ +import { RasterLayer } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const terrainRGB: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + center: [121.434765, 31.256735], + zoom: 4, + }, + }); + + const layer = new RasterLayer() + .source( + 'https://tiles{1-3}.geovisearth.com/base/v1/terrain_rgb/{z}/{x}/{y}?format=png&tmsIds=w&token=b2a0cfc132cd60b61391b9dd63c15711eadb9b38a9943e3f98160d5710aef788', + { + parser: { + type: 'rasterTile', + dataType: 'terrainRGB', + tileSize: 256, + zoomOffset: 0, + }, + }, + ) + .style({ + clampLow: false, + clampHigh: false, + domain: [0, 7000], + rampColors: { + type: 'linear', + colors: ['#d73027', '#fc8d59', '#fee08b', '#d9ef8b', '#91cf60', '#1a9850'], + positions: [0, 200, 500, 1000, 2000, 7000], // '#1a9850' + }, + }); + + scene.addLayer(layer); + + return scene; +}; diff --git a/examples/demos/tile/vector.ts b/examples/demos/tile/vector-city.ts similarity index 78% rename from examples/demos/tile/vector.ts rename to examples/demos/tile/vector-city.ts index 55322f86367..c9a674c65d8 100644 --- a/examples/demos/tile/vector.ts +++ b/examples/demos/tile/vector-city.ts @@ -1,20 +1,18 @@ import { PointLayer, PolygonLayer, Scene, Source } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; import { Protocol } from 'pmtiles'; -import type { RenderDemoOptions } from '../../types'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; const protocol = new Protocol(); Scene.addProtocol('pmtiles', protocol.tile); -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const vectorCity: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [11.2438, 43.7799], zoom: 12.83, - }), + }, }); const source = new Source( @@ -121,22 +119,18 @@ export function MapRender(options: RenderDemoOptions) { .style({ opacity: 1, }); - // TODO:Mask 和缩放取消 - scene.on('loaded', () => { - scene.addLayer(layer); - scene.addLayer(boundaries); - scene.addLayer(natural); - scene.addLayer(buildings); - scene.addLayer(transit); - scene.addLayer(roads); - scene.addLayer(water); - scene.addLayer(point); - layer.on('inited', () => { - console.log(layer.tileLayer?.getLayers()); - }); - if (window['screenshot']) { - window['screenshot'](); - } + scene.addLayer(layer); + scene.addLayer(boundaries); + scene.addLayer(natural); + scene.addLayer(buildings); + scene.addLayer(transit); + scene.addLayer(roads); + scene.addLayer(water); + scene.addLayer(point); + layer.on('inited', () => { + console.log(layer.tileLayer?.getLayers()); }); -} + + return scene; +}; diff --git a/examples/demos/tile/world.ts b/examples/demos/tile/vector-line.ts similarity index 64% rename from examples/demos/tile/world.ts rename to examples/demos/tile/vector-line.ts index 345041d70cc..7127273854d 100644 --- a/examples/demos/tile/world.ts +++ b/examples/demos/tile/vector-line.ts @@ -1,20 +1,18 @@ import { LineLayer, Scene, Source } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; import { Protocol } from 'pmtiles'; -import type { RenderDemoOptions } from '../../types'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; const protocol = new Protocol(); Scene.addProtocol('pmtiles', protocol.tile); -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const vectorLine: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [116.420818, 39.923852], zoom: 14, - }), + }, }); const source = new Source( @@ -37,11 +35,7 @@ export function MapRender(options: RenderDemoOptions) { opacity: 0.8, }); - scene.on('loaded', () => { - scene.addLayer(linelayer); + scene.addLayer(linelayer); - if (window['screenshot']) { - window['screenshot'](); - } - }); -} + return scene; +}; diff --git a/examples/demos/tile/vector-perf.ts b/examples/demos/tile/vector-perf.ts new file mode 100644 index 00000000000..3492ae5ea4a --- /dev/null +++ b/examples/demos/tile/vector-perf.ts @@ -0,0 +1,78 @@ +import { LineLayer, PolygonLayer, Source } from '@antv/l7'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + +export const vectorPerf: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { + zoom: 4.5, + center: [116.412427, 39.303573], + }, + }); + const url = + 'https://mvt.amap.com/district/CHN3/{z}/{x}/{y}/4096?key=309f07ac6bc48160e80b480ae511e1e9&version='; + const source = new Source(url, { + parser: { + type: 'mvt', + tileSize: 256, + warp: false, + }, + }); + + const colors: Record = {}; + const getColorByAdcode = function (adcode: string) { + if (!colors[adcode]) { + const gb = Math.floor(Math.random() * 155 + 50); + colors[adcode] = 'rgb(' + gb + ',' + gb + ',255)'; + } + + return colors[adcode]; + }; + // 绿地 + const fill = new PolygonLayer({ + sourceLayer: 'CHN_Districts', + featureId: 'adcode', + }) + .source(source) + .shape('fill') + // .color('#f00'); + .color('adcode', getColorByAdcode); + + fill.on('click', (e) => { + console.log(e); + }); + + const line = new LineLayer({ + sourceLayer: 'CHN_Districts_L', + }) + .source(source) + .shape('simple') + .color('#fee0d2'); + + const line2 = new LineLayer({ + sourceLayer: 'CHN_Citys_L', + }) + .source(source) + .shape('line') + .size(0.6) + .color('#fc9272'); + + const line3 = new LineLayer({ + sourceLayer: 'CHN_Provinces_L', + }) + .source(source) + .shape('line') + .size(0.6) + .color('#de2d26'); + + scene.addLayer(fill); + // scene.addLayer(line); + // scene.addLayer(line2); + // scene.addLayer(line3); + // scene.addLayer(line2); + // const debugerLayer = new TileDebugLayer({ usage: 'basemap' }); + // scene.addLayer(debugerLayer); + + return scene; +}; diff --git a/examples/demos/tile/usa.ts b/examples/demos/tile/vector-usa.ts similarity index 69% rename from examples/demos/tile/usa.ts rename to examples/demos/tile/vector-usa.ts index ccd96f96303..2bbb48e0b43 100644 --- a/examples/demos/tile/usa.ts +++ b/examples/demos/tile/vector-usa.ts @@ -1,19 +1,18 @@ import { LineLayer, PolygonLayer, Scene, Source } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; import { Protocol } from 'pmtiles'; -import type { RenderDemoOptions } from '../../types'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; + const protocol = new Protocol(); Scene.addProtocol('pmtiles', protocol.tile); -export function MapRender(options: RenderDemoOptions) { - const scene = new Scene({ - id: 'map', - renderer: options.renderer, - map: new allMap[options.map]({ - style: 'light', +export const vectorUSA: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { center: [-82.96875, 37.71024], zoom: 5, - }), + }, }); const source = new Source( @@ -48,12 +47,8 @@ export function MapRender(options: RenderDemoOptions) { opacity: 0.8, }); - scene.on('loaded', () => { - scene.addLayer(layer); - scene.addLayer(linelayer); + scene.addLayer(layer); + scene.addLayer(linelayer); - if (window['screenshot']) { - window['screenshot'](); - } - }); -} + return scene; +}; diff --git a/examples/demos/webgpu/boids.ts b/examples/demos/webgpu/boids.ts index cdb4e070fe4..008679e7ce7 100644 --- a/examples/demos/webgpu/boids.ts +++ b/examples/demos/webgpu/boids.ts @@ -9,17 +9,32 @@ import { VertexStepMode, WebGPUDeviceContribution, } from '@antv/g-device-api'; -import type { RenderDemoOptions } from '../../types'; +import type { Scene } from '@antv/l7-scene'; +import type { TestCase } from '../../types'; import { generateTexture } from './utils/common'; -export async function MapRender(options: RenderDemoOptions) { - const dom = document.getElementById('map') as HTMLDivElement; +export const boids: TestCase = async (options) => { + const dom = options.id as HTMLDivElement; // 创建 canvas const $canvas = document.createElement('canvas'); dom.appendChild($canvas); // 设置 canvas 大小 $canvas.width = dom.clientWidth; $canvas.height = dom.clientHeight; + + const device = await render($canvas); + + const scene = { + destroy: () => { + dom.removeChild($canvas); + device.destroy(); + }, + }; + + return scene as Scene; +}; + +async function render($canvas: HTMLCanvasElement) { const deviceContribution = new WebGPUDeviceContribution({ shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', }); @@ -385,4 +400,6 @@ export async function MapRender(options: RenderDemoOptions) { }; frame(); + + return device; } diff --git a/examples/demos/webgpu/compute_texture.ts b/examples/demos/webgpu/compute-texture.ts similarity index 94% rename from examples/demos/webgpu/compute_texture.ts rename to examples/demos/webgpu/compute-texture.ts index 5e0e6ff7431..5b5b6fa9311 100644 --- a/examples/demos/webgpu/compute_texture.ts +++ b/examples/demos/webgpu/compute-texture.ts @@ -1,15 +1,30 @@ import { BufferUsage, WebGPUDeviceContribution } from '@antv/g-device-api'; -import type { RenderDemoOptions } from '../../types'; +import type { Scene } from '@antv/l7-scene'; +import type { TestCase } from '../../types'; import { createTexture, generateTexture } from './utils/common'; -export async function MapRender(options: RenderDemoOptions) { - const dom = document.getElementById('map') as HTMLDivElement; +export const computeTexture: TestCase = async (options) => { + const dom = options.id as HTMLDivElement; // 创建 canvas const $canvas = document.createElement('canvas'); dom.appendChild($canvas); // 设置 canvas 大小 $canvas.width = dom.clientWidth; $canvas.height = dom.clientHeight; + + const device = await render($canvas); + + const scene = { + destroy: () => { + dom.removeChild($canvas); + device.destroy(); + }, + }; + + return scene as Scene; +}; + +async function render($canvas: HTMLCanvasElement) { const deviceContribution = new WebGPUDeviceContribution({ shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', }); @@ -225,4 +240,6 @@ export async function MapRender(options: RenderDemoOptions) { // const data = await readback.readBuffer(particleBuffers[1], 0, new Float32Array(numParticles*4)); // console.log(data); // frame(); + + return device; } diff --git a/examples/demos/webgpu/heatmap_grid.ts b/examples/demos/webgpu/heatmap_grid.ts deleted file mode 100644 index fc9dccb3bf2..00000000000 --- a/examples/demos/webgpu/heatmap_grid.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { HeatmapLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; - -export function MapRender(option: { map: string; renderer: string }) { - const scene = new Scene({ - id: 'map', - renderer: option.renderer, - enableWebGPU: true, - shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', - map: new allMap[option.map || 'Map']({ - style: 'light', - center: [121.434765, 31.256735], - zoom: 14.83, - }), - }); - - scene.on('loaded', () => { - fetch('https://gw.alipayobjects.com/os/basement_prod/513add53-dcb2-4295-8860-9e7aa5236699.json') - .then((res) => res.json()) - .then((data) => { - const layer = new HeatmapLayer({ autoFit: true }) - .source(data, { - transforms: [ - { - type: 'hexagon', - size: 100, - field: 'h12', - method: 'sum', - }, - ], - }) - .size('sum', [0, 60]) - .shape('squareColumn') - .active(true) - .style({ - opacity: 1, - }) - .color( - 'sum', - [ - '#094D4A', - '#146968', - '#1D7F7E', - '#289899', - '#34B6B7', - '#4AC5AF', - '#5FD3A6', - '#7BE39E', - '#A1EDB8', - '#CEF8D6', - ].reverse(), - ); - scene.startAnimate(); - scene.addLayer(layer); - scene.render(); - }); - }); -} diff --git a/examples/demos/webgpu/heatmap_grid3d.ts b/examples/demos/webgpu/heatmap_grid3d.ts deleted file mode 100644 index 1665dbf2d2d..00000000000 --- a/examples/demos/webgpu/heatmap_grid3d.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { HeatmapLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; - -export function MapRender(option: { map: string; renderer: string }) { - const scene = new Scene({ - id: 'map', - renderer: option.renderer, - enableWebGPU: true, - shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', - map: new allMap[option.map || 'Map']({ - style: 'light', - center: [121.434765, 31.256735], - zoom: 14.83, - }), - }); - - scene.on('loaded', () => { - fetch('https://gw.alipayobjects.com/os/basement_prod/d3564b06-670f-46ea-8edb-842f7010a7c6.json') - .then((res) => res.json()) - .then((data) => { - const layer = new HeatmapLayer({ autoFit: true }) - .source(data, { - transforms: [ - { - type: 'grid', - size: 150000, - field: 'mag', - method: 'sum', - }, - ], - }) - .size('sum', (sum) => { - return sum * 2000; - }) - .shape('hexagonColumn') - .style({ - coverage: 0.8, - angle: 0, - }) - .active(true) - .color( - 'count', - [ - '#0B0030', - '#100243', - '#100243', - '#1B048B', - '#051FB7', - '#0350C1', - '#0350C1', - '#0072C4', - '#0796D3', - '#2BA9DF', - '#30C7C4', - '#6BD5A0', - '#A7ECB2', - '#D0F4CA', - ].reverse(), - ); - scene.addLayer(layer); - }); - }); -} diff --git a/examples/demos/webgpu/heatmap_normal.ts b/examples/demos/webgpu/heatmap_normal.ts deleted file mode 100644 index 51c13c67f94..00000000000 --- a/examples/demos/webgpu/heatmap_normal.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { HeatmapLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; - -export function MapRender(option: { map: string; renderer: string }) { - const scene = new Scene({ - id: 'map', - renderer: option.renderer, - enableWebGPU: true, - shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', - map: new allMap[option.map || 'Map']({ - style: 'light', - center: [121.434765, 31.256735], - zoom: 14.83, - }), - }); - - scene.on('loaded', () => { - fetch('https://gw.alipayobjects.com/os/basement_prod/d3564b06-670f-46ea-8edb-842f7010a7c6.json') - .then((res) => res.json()) - .then((data) => { - const layer = new HeatmapLayer({ autoFit: true }) - .source(data) - .shape('heatmap') - .size('mag', [0, 1.0]) // weight映射通道 - .style({ - intensity: 2, - radius: 20, - opacity: 1.0, - rampColors: { - colors: ['#FF4818', '#F7B74A', '#FFF598', '#91EABC', '#2EA9A1', '#206C7C'].reverse(), - positions: [0, 0.2, 0.4, 0.6, 0.8, 1.0], - }, - }); - scene.addLayer(layer); - }); - }); -} diff --git a/examples/demos/webgpu/idw.ts b/examples/demos/webgpu/idw.ts index 7e9c9af0516..c8a6c9fc081 100644 --- a/examples/demos/webgpu/idw.ts +++ b/examples/demos/webgpu/idw.ts @@ -1,12 +1,14 @@ // import Flatbush from 'flatbush'; // https://github.com/mourner/kdbush +import type { Scene } from '@antv/l7-scene'; import KDBush from 'kdbush'; +import type { TestCase } from '../../types'; -export async function MapRender() { +export const idw: TestCase = async (options) => { const rawdata = await ( await fetch('https://mdn.alipayobjects.com/afts/file/A*yHeJTaQ6iVsAAAAAAAAAAAAADrd2AQ/aqi.json') ).json(); - const data = rawdata.map((row) => { + const data = rawdata.map((row: any) => { const { CityCode, Area, PositionName, Latitude, Longitude, AQI } = row; return { CityCode, @@ -24,4 +26,10 @@ export async function MapRender() { dataIndex.finish(); console.log(dataIndex); -} + + const scene = { + destroy: () => {}, + }; + + return scene as Scene; +}; diff --git a/examples/demos/webgpu/index.ts b/examples/demos/webgpu/index.ts index 728c95eaa18..21af66057d2 100644 --- a/examples/demos/webgpu/index.ts +++ b/examples/demos/webgpu/index.ts @@ -1,23 +1,4 @@ -export { MapRender as boids } from './boids'; -export { MapRender as compute_texture } from './compute_texture'; -export { MapRender as heatmap_grid } from './heatmap_grid'; -export { MapRender as heatmap_grid3d } from './heatmap_grid3d'; -export { MapRender as heatmap_normal } from './heatmap_normal'; -export { MapRender as WebGL_IDW } from './idw'; -export { MapRender as line_normal } from './line_normal'; -export { MapRender as perf } from './perf'; -export { MapRender as perf_animate } from './perf-animate'; -export { MapRender as point_column } from './point_column'; -export { MapRender as point_fill } from './point_fill'; -export { MapRender as point_image } from './point_image'; -export { MapRender as point_text } from './point_text'; -export { MapRender as polygon_extrude } from './polygon_extrude'; -export { MapRender as polygon_fill } from './polygon_fill'; -export { MapRender as polygon_texture } from './polygon_texture'; -export { MapRender as polygon_water } from './polygon_water'; -export { MapRender as raster_dem } from './raster_dem'; -export { MapRender as raster_image } from './raster_image'; -export { MapRender as raster_multiband } from './raster_multiband'; -export { MapRender as raster_ndvi } from './raster_ndvi'; -export { MapRender as raster_tiff } from './raster_tiff'; -export { MapRender as texture } from './texture'; +export { boids } from './boids'; +export { computeTexture } from './compute-texture'; +export { idw } from './idw'; +export { perf } from './perf'; diff --git a/examples/demos/webgpu/perf-animate.ts b/examples/demos/webgpu/perf-animate.ts deleted file mode 100644 index f6fc29a5816..00000000000 --- a/examples/demos/webgpu/perf-animate.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { LineLayer, PointLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import Stats from 'stats.js'; - -export function MapRender(option: { map: string; renderer: string; animate: boolean }) { - option.animate = true; - const scene = new Scene({ - id: 'map', - renderer: option.renderer, - enableWebGPU: true, - shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', - map: new allMap[option.map || 'Map']({ - style: 'light', - center: [40, 40.16797], - zoom: 2.5, - }), - }); - - scene.addImage( - 'plane', - 'https://gw.alipayobjects.com/zos/bmw-prod/0ca1668e-38c2-4010-8568-b57cb33839b9.svg', - ); - scene.on('loaded', () => { - Promise.all([ - fetch( - 'https://gw.alipayobjects.com/os/bmw-prod/2960e1fc-b543-480f-a65e-d14c229dd777.json', - ).then((d) => d.json()), - fetch( - 'https://gw.alipayobjects.com/os/basement_prod/4472780b-fea1-4fc2-9e4b-3ca716933dc7.json', - ).then((d) => d.text()), - fetch( - 'https://gw.alipayobjects.com/os/basement_prod/a5ac7bce-181b-40d1-8a16-271356264ad8.json', - ).then((d) => d.text()), - ]).then(function onLoad([world, dot, flyline]) { - const dotData = eval(dot); - // @ts-ignore - let flydata = eval(flyline).map((item) => { - // @ts-ignore - const latlng1 = item.from.split(',').map((e) => { - return e * 1; - }); - // @ts-ignore - const latlng2 = item.to.split(',').map((e) => { - return e * 1; - }); - return { coord: [latlng1, latlng2] }; - }); - - // 2400 - flydata = new Array(50).fill(flydata).flat(); - - const worldLine = new LineLayer().source(world).color('#41fc9d').size(0.5).style({ - opacity: 0.4, - }); - const dotPoint = new PointLayer() - .source(dotData, { - parser: { - type: 'json', - x: 'lng', - y: 'lat', - }, - }) - .shape('circle') - .color('#ffed11') - .animate({ enable: option.animate }) - .size(40); - const flyLine = new LineLayer({ blend: 'normal' }) - .source(flydata, { - parser: { - type: 'json', - coordinates: 'coord', - }, - }) - .color('#ff6b34') - .texture('plane') - .shape('arc') - .size(15) - .animate( - !option.animate - ? { enable: false } - : { - duration: 1, - interval: 0.2, - trailLength: 0.5, - }, - ) - .style({ - textureBlend: 'replace', - lineTexture: true, // 开启线的贴图功能 - iconStep: 10, // 设置贴图纹理的间距 - }); - - const flyLine2 = new LineLayer() - .source(flydata, { - parser: { - type: 'json', - coordinates: 'coord', - }, - }) - .color('#ff6b34') - .shape('arc') - .size(1) - .style({ - lineType: 'dash', - dashArray: [5, 5], - opacity: 0.5, - }); - scene.addLayer(worldLine); - scene.addLayer(dotPoint); - scene.addLayer(flyLine2); - scene.addLayer(flyLine); - }); - - // stats.js - const stats = new Stats(); - stats.showPanel(0); - const $stats = stats.dom; - $stats.style.position = 'absolute'; - $stats.style.left = '0px'; - $stats.style.bottom = '0px'; - document.body.appendChild($stats); - - const tick = () => { - stats.update(); - - requestAnimationFrame(tick); - }; - tick(); - }); -} diff --git a/examples/demos/webgpu/perf.ts b/examples/demos/webgpu/perf.ts index 386a321b9f5..bb64a6cbb1d 100644 --- a/examples/demos/webgpu/perf.ts +++ b/examples/demos/webgpu/perf.ts @@ -1,53 +1,45 @@ -import { PointLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; +import { PointLayer } from '@antv/l7'; import Stats from 'stats.js'; +import data from '../../data/globe-earthquake-mag.json'; +import type { TestCase } from '../../types'; +import { CaseScene } from '../../utils'; -export function MapRender(option: { map: string; renderer: string }) { - const scene = new Scene({ - id: 'map', - // renderer: 'regl', - renderer: option.renderer, - enableWebGPU: true, - shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', - map: new allMap[option.map || 'Map']({ - style: 'light', +export const perf: TestCase = async (options) => { + const scene = await CaseScene({ + ...options, + mapConfig: { pitch: 20, center: [120, 20], zoom: 3, - }), - }); - scene.on('loaded', () => { - fetch('https://gw.alipayobjects.com/os/basement_prod/d3564b06-670f-46ea-8edb-842f7010a7c6.json') - .then((res) => res.json()) - .then((data) => { - data.features = [ - ...data.features, - ...data.features, - ...data.features, - ...data.features, - ...data.features, - ...data.features, - ...data.features, - ...data.features, - ...data.features, - ...data.features, - ]; - const pointLayer = new PointLayer({}) - .source(data) - .shape('circle') - .size(15) - .color('mag', (mag) => { - return mag > 4.5 ? '#5B8FF9' : '#5CCEA1'; - }) - .active(true) - .style({ - opacity: 0.6, - strokeWidth: 3, - }); - scene.addLayer(pointLayer); - }); + }, }); + data.features = [ + ...data.features, + ...data.features, + ...data.features, + ...data.features, + ...data.features, + ...data.features, + ...data.features, + ...data.features, + ...data.features, + ...data.features, + ]; + const pointLayer = new PointLayer({}) + .source(data) + .shape('circle') + .size(15) + .color('mag', (mag) => { + return mag > 4.5 ? '#5B8FF9' : '#5CCEA1'; + }) + .active(true) + .style({ + opacity: 0.6, + strokeWidth: 3, + }); + scene.addLayer(pointLayer); + // stats.js const stats = new Stats(); stats.showPanel(0); @@ -55,7 +47,8 @@ export function MapRender(option: { map: string; renderer: string }) { $stats.style.position = 'absolute'; $stats.style.left = '0px'; $stats.style.bottom = '0px'; - document.body.appendChild($stats); + const dom = options.id as HTMLDivElement; + dom.appendChild($stats); const tick = () => { stats.update(); @@ -63,4 +56,6 @@ export function MapRender(option: { map: string; renderer: string }) { requestAnimationFrame(tick); }; tick(); -} + + return scene; +}; diff --git a/examples/demos/webgpu/point_column.ts b/examples/demos/webgpu/point_column.ts deleted file mode 100644 index 65a46a46fc5..00000000000 --- a/examples/demos/webgpu/point_column.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { PointLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; - -export function MapRender(option: { map: string; renderer: string }) { - const scene = new Scene({ - id: 'map', - renderer: option.renderer, - enableWebGPU: true, - shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', - map: new allMap[option.map || 'Map']({ - style: 'light', - center: [121.400257, 31.25287], - zoom: 14.55, - rotation: 134.9507, - }), - }); - fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json') - .then((res) => res.json()) - .then((data) => { - const pointLayer = new PointLayer({}) - .source(data, { - parser: { - type: 'json', - x: 'longitude', - y: 'latitude', - }, - }) - .shape('name', ['cylinder', 'triangleColumn', 'hexagonColumn', 'squareColumn']) - .active(true) - .size('unit_price', (h) => { - return [6, 6, 100]; - }) - .color('name', ['#739DFF', '#61FCBF', '#FFDE74', '#FF896F']) - .style({ - opacity: 1, - }); - scene.addLayer(pointLayer); - }); -} diff --git a/examples/demos/webgpu/point_fill.ts b/examples/demos/webgpu/point_fill.ts deleted file mode 100644 index 15ad86152a8..00000000000 --- a/examples/demos/webgpu/point_fill.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { PointLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; - -export function MapRender(option: { map: string; renderer: string }) { - const scene = new Scene({ - id: 'map', - renderer: option.renderer, - enableWebGPU: true, - shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', - map: new allMap[option.map || 'Map']({ - style: 'light', - center: [121.435159, 31.256971], - zoom: 14.89, - minZoom: 10, - }), - }); - scene.on('loaded', () => { - fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json') - .then((res) => res.json()) - .then((data) => { - const pointLayer = new PointLayer({}) - .source(data, { - parser: { - type: 'json', - x: 'longitude', - y: 'latitude', - }, - }) - .shape('name', [ - 'circle', - 'triangle', - 'square', - 'pentagon', - 'hexagon', - 'octogon', - 'hexagram', - 'rhombus', - 'vesica', - ]) - .size('unit_price', [10, 25]) - .active(true) - .color('name', ['#5B8FF9', '#5CCEA1', '#5D7092', '#F6BD16', '#E86452']) - .style({ - opacity: 1, - strokeWidth: 2, - }); - - scene.addLayer(pointLayer); - }); - }); -} diff --git a/examples/demos/webgpu/point_text.ts b/examples/demos/webgpu/point_text.ts deleted file mode 100644 index 91a3b0f87a5..00000000000 --- a/examples/demos/webgpu/point_text.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { PointLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; - -export function MapRender(option: { map: string; renderer: string }) { - const scene = new Scene({ - id: 'map', - renderer: option.renderer, - enableWebGPU: true, - shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', - map: new allMap[option.map || 'Map']({ - style: 'light', - center: [121.434765, 31.256735], - zoom: 14.83, - }), - }); - scene.addImage( - '00', - 'https://gw.alipayobjects.com/zos/basement_prod/604b5e7f-309e-40db-b95b-4fac746c5153.svg', - ); - scene.addImage( - '01', - 'https://gw.alipayobjects.com/zos/basement_prod/30580bc9-506f-4438-8c1a-744e082054ec.svg', - ); - scene.addImage( - '02', - 'https://gw.alipayobjects.com/zos/basement_prod/7aa1f460-9f9f-499f-afdf-13424aa26bbf.svg', - ); - scene.on('loaded', () => { - fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json') - .then((res) => res.json()) - .then((data) => { - const imageLayerText = new PointLayer() - .source(data, { - parser: { - type: 'json', - x: 'longitude', - y: 'latitude', - }, - }) - .shape('name', 'text') - .color('#f00') - .size(25) - .style({ - textOffset: [0, 20], - }); - scene.addLayer(imageLayerText); - }); - }); -} diff --git a/examples/demos/webgpu/polygon_extrude.ts b/examples/demos/webgpu/polygon_extrude.ts deleted file mode 100644 index 89b3f8cf042..00000000000 --- a/examples/demos/webgpu/polygon_extrude.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { PolygonLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; - -export function MapRender(option: { map: string; renderer: string }) { - console.log(option); - const scene = new Scene({ - id: 'map', - renderer: option.renderer, - enableWebGPU: true, - shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', - map: new allMap[option.map || 'Map']({ - style: 'light', - center: [121.434765, 31.256735], - zoom: 14.83, - }), - }); - - const colors = [ - '#87CEFA', - '#00BFFF', - - '#7FFFAA', - '#00FF7F', - '#32CD32', - - '#F0E68C', - '#FFD700', - - '#FF7F50', - '#FF6347', - '#FF0000', - ]; - scene.on('loaded', () => { - fetch('https://gw.alipayobjects.com/os/bmw-prod/94763191-2816-4c1a-8d0d-8bcf4181056a.json') - .then((res) => res.json()) - .then((data) => { - const filllayer = new PolygonLayer({ - name: 'fill', - zIndex: 3, - autoFit: true, - }) - .source(data) - .shape('extrude') - .active(true) - .size('unit_price', (unit_price) => unit_price) - .color('count', ['#f2f0f7', '#dadaeb', '#bcbddc', '#9e9ac8', '#756bb1', '#54278f']) - .style({ - pickLight: true, - - opacity: 1, - }); - scene.addLayer(filllayer); - }); - }); -} diff --git a/examples/demos/webgpu/polygon_fill.ts b/examples/demos/webgpu/polygon_fill.ts deleted file mode 100644 index 1028e5efae0..00000000000 --- a/examples/demos/webgpu/polygon_fill.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { PolygonLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; - -export function MapRender(option: { map: string; renderer: string }) { - const scene = new Scene({ - id: 'map', - renderer: option.renderer, - enableWebGPU: true, - shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', - map: new allMap[option.map || 'Map']({ - style: 'light', - center: [121.434765, 31.256735], - zoom: 14.83, - }), - }); - - const data = { - type: 'FeatureCollection', - features: [ - { - type: 'Feature', - properties: { - testOpacity: 0.8, - }, - geometry: { - type: 'Polygon', - coordinates: [ - [ - [113.8623046875, 30.031055426540206], - [116.3232421875, 30.031055426540206], - [116.3232421875, 31.090574094954192], - [113.8623046875, 31.090574094954192], - [113.8623046875, 30.031055426540206], - ], - ], - }, - }, - ], - }; - - const data2 = { - type: 'FeatureCollection', - features: [ - { - type: 'Feature', - properties: { - testOpacity: 0.8, - }, - geometry: { - type: 'Polygon', - coordinates: [ - [ - [113.8623046875, 30.031055426540206], - [115.3232421875, 30.031055426540206], - [115.3232421875, 31.090574094954192], - [113.8623046875, 31.090574094954192], - [113.8623046875, 30.031055426540206], - ], - ], - }, - }, - ], - }; - - const layer = new PolygonLayer({ - autoFit: true, - }) - .source(data) - .shape('fill') - .color('red') - .active(true) - .style({ - opacity: 0.5, - opacityLinear: { - enable: true, - dir: 'in', - }, - }); - - scene.on('loaded', () => { - scene.addLayer(layer); - }); -} diff --git a/examples/demos/webgpu/polygon_texture.ts b/examples/demos/webgpu/polygon_texture.ts deleted file mode 100644 index 0ee6508a1ed..00000000000 --- a/examples/demos/webgpu/polygon_texture.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { PolygonLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; - -export function MapRender(option: { map: string; renderer: string }) { - const scene = new Scene({ - id: 'map', - renderer: option.renderer, - enableWebGPU: true, - shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', - map: new allMap[option.map || 'Map']({ - style: 'light', - center: [121.434765, 31.256735], - zoom: 14.83, - }), - }); - - scene.on('loaded', () => { - fetch('https://geo.datav.aliyun.com/areas_v3/bound/330000.json') - .then((res) => res.json()) - .then((data) => { - const provincelayerTop = new PolygonLayer({ - autoFit: true, - }) - .source(data) - .size(1000) - .shape('extrude') - .size(10000) - .color('#0DCCFF') - // .active({ - // color: 'rgb(100,230,255)', - // }) - .style({ - heightfixed: true, - // pickLight: true, - mapTexture: - 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*bm0eRKOCcNoAAAAAAAAAAAAADmJ7AQ/original', - // mapTexture:'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*3UcORbAv_zEAAAAAAAAAAAAADmJ7AQ/original', - // raisingHeight: 10000, - opacity: 0.8, - // sidesurface: false, - }); - scene.addLayer(provincelayerTop); - // scene.startAnimate(); - }); - }); -} diff --git a/examples/demos/webgpu/polygon_water.ts b/examples/demos/webgpu/polygon_water.ts deleted file mode 100644 index 2d118c266c1..00000000000 --- a/examples/demos/webgpu/polygon_water.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { PolygonLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; - -export function MapRender(option: { map: string; renderer: string }) { - const scene = new Scene({ - id: 'map', - renderer: option.renderer, - enableWebGPU: true, - shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', - map: new allMap[option.map || 'Map']({ - style: 'light', - center: [121.434765, 31.256735], - zoom: 14.83, - }), - }); - - const layer = new PolygonLayer({ - autoFit: true, - }) - .source({ - type: 'FeatureCollection', - features: [ - { - type: 'Feature', - properties: {}, - geometry: { - type: 'Polygon', - coordinates: [ - [ - [104.4140625, 35.460669951495305], - [114.4140625, 35.460669951495305], - [114.4140625, 30.460669951495305], - [104.4140625, 30.460669951495305], - [104.4140625, 35.460669951495305], - ], - ], - }, - }, - ], - }) - .shape('water') - .color('#1E90FF') - .style({ - speed: 0.4, - // waterTexture: - // 'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*EojwT4VzSiYAAAAAAAAAAAAAARQnAQ', - }) - .animate(true); - - scene.on('loaded', () => { - scene.addLayer(layer); - }); -} diff --git a/examples/demos/webgpu/raster_dem.ts b/examples/demos/webgpu/raster_dem.ts deleted file mode 100644 index 08bb1a57b0a..00000000000 --- a/examples/demos/webgpu/raster_dem.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { RasterLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; -import * as GeoTIFF from 'geotiff'; - -export function MapRender(option: { map: string; renderer: 'regl' | 'device' }) { - const scene = new Scene({ - id: 'map', - renderer: option.renderer, - enableWebGPU: true, - shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', - map: new allMap[option.map || 'Map']({ - style: 'light', - center: [121.434765, 31.256735], - zoom: 3, - }), - }); - async function getTiffData() { - const response = await fetch( - 'https://gw.alipayobjects.com/os/rmsportal/XKgkjjGaAzRyKupCBiYW.dat', - ); - const arrayBuffer = await response.arrayBuffer(); - return arrayBuffer; - } - scene.on('loaded', async () => { - const tiffdata = await getTiffData(); - const tiff = await GeoTIFF.fromArrayBuffer(tiffdata); - const image = await tiff.getImage(); - const width = image.getWidth(); - const height = image.getHeight(); - const values = await image.readRasters(); - console.log(values); - - const layer = new RasterLayer(); - layer - .source(values[0], { - parser: { - type: 'raster', - width, - height, - extent: [73.482190241, 3.82501784112, 135.106618732, 57.6300459963], - }, - }) - .style({ - opacity: 1, - // clampLow: false, - // clampHigh: false, - domain: [0, 10000], - rampColors: { - type: 'custom', - colors: [ - '#b2182b', - '#d6604d', - '#f4a582', - '#fddbc7', - '#f7f7f7', - '#d1e5f0', - '#92c5de', - '#4393c3', - '#2166ac', - ], - positions: [0, 50, 200, 500, 2000, 3000, 4000, 5000, 8000, 10000], - }, - }); - - scene.addLayer(layer); - scene.startAnimate(); - }); -} diff --git a/examples/demos/webgpu/raster_image.ts b/examples/demos/webgpu/raster_image.ts deleted file mode 100644 index b4b806d27e2..00000000000 --- a/examples/demos/webgpu/raster_image.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { ImageLayer, Scene } from '@antv/l7'; -import * as allMap from '@antv/l7-maps'; - -export function MapRender(option: { map: string; renderer: string }) { - const scene = new Scene({ - id: 'map', - renderer: option.renderer, - enableWebGPU: true, - shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', - map: new allMap[option.map || 'Map']({ - style: 'light', - center: [115.5268, 34.3628], - zoom: 7, - }), - }); - scene.on('loaded', () => { - const layer = new ImageLayer({}); - layer.source( - 'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*8SUaRr7bxNsAAAAAAAAAAABkARQnAQ', - { - parser: { - type: 'image', - extent: [113.1277263548, 32.3464238863, 118.1365790452, 36.4786759137], - }, - }, - ); - scene.addLayer(layer); - }); -} diff --git a/examples/demos/webgpu/raster_multiband.ts b/examples/demos/webgpu/raster_multiband.ts deleted file mode 100644 index e630bc3a8f8..00000000000 --- a/examples/demos/webgpu/raster_multiband.ts +++ /dev/null @@ -1,50 +0,0 @@ -// @ts-ignore -import { RasterLayer, Scene } from '@antv/l7'; -// @ts-ignore -import * as allMap from '@antv/l7-maps'; -import * as GeoTIFF from 'geotiff'; - -async function getTiffData(url: string) { - const response = await fetch(url); - const arrayBuffer = await response.arrayBuffer(); - return arrayBuffer; -} - -export function MapRender(option: { map: string; renderer: 'device' | 'regl' }) { - const scene = new Scene({ - id: 'map', - renderer: option.renderer, - enableWebGPU: true, - shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', - map: new allMap[option.map || 'Map']({ - center: [130.5, 47], - zoom: 10.5, - }), - }); - scene.on('loaded', () => { - addLayer(); - }); - - async function addLayer() { - const url1 = 'https://gw.alipayobjects.com/zos/raptor/1667832825992/LC08_3857_clip_2.tif'; - const tiffdata = await getTiffData(url1); - const layer = new RasterLayer({ zIndex: 10 }); - const tiff = await GeoTIFF.fromArrayBuffer(tiffdata); - const image1 = await tiff.getImage(); - const value = await image1.readRasters(); - layer - .source(value, { - parser: { - type: 'rgb', - width: value.width, - height: value.height, - bands: [5, 4, 3], - extent: [130.39565357746957, 46.905730725742366, 130.73364094187343, 47.10217234153133], - }, - }) - .style({ - opacity: 1, - }); - scene.addLayer(layer); - } -} diff --git a/examples/demos/webgpu/raster_ndvi.ts b/examples/demos/webgpu/raster_ndvi.ts deleted file mode 100644 index 0cdbd47ed5f..00000000000 --- a/examples/demos/webgpu/raster_ndvi.ts +++ /dev/null @@ -1,54 +0,0 @@ -// @ts-ignore -import { RasterLayer, Scene } from '@antv/l7'; -// @ts-ignore -import * as allMap from '@antv/l7-maps'; -import * as GeoTIFF from 'geotiff'; - -async function getTiffData(url: string) { - const response = await fetch(url); - const arrayBuffer = await response.arrayBuffer(); - return arrayBuffer; -} - -export function MapRender(option: { map: string; renderer: 'device' | 'regl' }) { - const scene = new Scene({ - id: 'map', - renderer: option.renderer, - enableWebGPU: true, - shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', - map: new allMap[option.map || 'Map']({ - center: [130.5, 47], - zoom: 10.5, - }), - }); - scene.on('loaded', () => { - addLayer(); - }); - - async function addLayer() { - const url1 = 'https://gw.alipayobjects.com/zos/raptor/1667832825992/LC08_3857_clip_2.tif'; - const tiffdata = await getTiffData(url1); - const layer = new RasterLayer({ zIndex: 10 }); - const tiff = await GeoTIFF.fromArrayBuffer(tiffdata); - const image1 = await tiff.getImage(); - const value = await image1.readRasters(); - layer - .source(value, { - parser: { - type: 'ndi', - width: value.width, - height: value.height, - bands: [3, 4], // 4 为 Band5是近红外(NIR)波段,3 为Band4是红光波段 - extent: [130.39565357746957, 46.905730725742366, 130.73364094187343, 47.10217234153133], - }, - }) - .style({ - domain: [-0.3, 0.5], - rampColors: { - colors: ['#ce4a2e', '#f0a875', '#fff8ba', '#bddd8a', '#5da73e', '#235117'], - positions: [0, 0.2, 0.4, 0.6, 0.8, 1.0], - }, - }); - scene.addLayer(layer); - } -} diff --git a/examples/demos/webgpu/raster_tiff.ts b/examples/demos/webgpu/raster_tiff.ts deleted file mode 100644 index b0d62dee3c0..00000000000 --- a/examples/demos/webgpu/raster_tiff.ts +++ /dev/null @@ -1,79 +0,0 @@ -// @ts-ignore -import { RasterLayer, Scene } from '@antv/l7'; -// @ts-ignore -import * as allMap from '@antv/l7-maps'; -import * as GeoTIFF from 'geotiff'; - -async function getTiffData() { - const response = await fetch( - 'https://gw.alipayobjects.com/zos/antvdemo/assets/light_clip/lightF182013.tiff', - ); - const arrayBuffer = await response.arrayBuffer(); - const tiff = await GeoTIFF.fromArrayBuffer(arrayBuffer); - const image = await tiff.getImage(); - const width = image.getWidth(); - const height = image.getHeight(); - const values = await image.readRasters(); - return { - data: values[0], - width, - height, - }; -} - -export function MapRender(option: { map: string; renderer: 'device' | 'regl' }) { - const scene = new Scene({ - id: 'map', - renderer: option.renderer, - enableWebGPU: true, - shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', - map: new allMap[option.map || 'Map']({ - center: [105, 37.5], - zoom: 2.5, - }), - }); - scene.on('loaded', () => { - addLayer(); - // scene.setBgColor('#aaa') - }); - - async function addLayer() { - const tiffdata = await getTiffData(); - - const layer = new RasterLayer({ - zIndex: 2, - visible: true, - }); - console.log(tiffdata); - layer - .source(tiffdata.data, { - parser: { - type: 'raster', - width: tiffdata.width, - height: tiffdata.height, - extent: [ - 73.4821902409999979, 3.8150178409999995, 135.1066187319999869, 57.6300459959999998, - ], - }, - }) - .style({ - clampLow: false, - clampHigh: false, - domain: [0, 90], - nodataValue: 0, - rampColors: { - colors: [ - 'rgba(92,58,16,0)', - 'rgba(92,58,16,0)', - '#fabd08', - '#f1e93f', - '#f1ff8f', - '#fcfff7', - ], - positions: [0, 0.05, 0.1, 0.25, 0.5, 1.0], - }, - }); - scene.addLayer(layer); - scene.startAnimate(); - } -} diff --git a/examples/demos/webgpu/template.ts b/examples/demos/webgpu/template.ts index 3caea9c71cd..030ce3023ce 100644 --- a/examples/demos/webgpu/template.ts +++ b/examples/demos/webgpu/template.ts @@ -1,16 +1,35 @@ import { WebGPUDeviceContribution } from '@antv/g-device-api'; -export async function MapRender(option: { map: string; renderer: 'regl' | 'device' }) { - const dom = document.getElementById('map') as HTMLDivElement; +import type { Scene } from '@antv/l7-scene'; +import type { TestCase } from '../../types'; + +export const template: TestCase = async (options) => { + const dom = options.id as HTMLDivElement; // 创建 canvas const $canvas = document.createElement('canvas'); dom.appendChild($canvas); // 设置 canvas 大小 $canvas.width = dom.clientWidth; $canvas.height = dom.clientHeight; + + const device = await render($canvas); + + const scene = { + destroy: () => { + dom.removeChild($canvas); + device.destroy(); + }, + }; + + return scene as Scene; +}; + +async function render($canvas: HTMLCanvasElement) { const deviceContribution = new WebGPUDeviceContribution({ shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', }); const swapChain = await deviceContribution.createSwapChain($canvas); swapChain.configureSwapChain($canvas.width, $canvas.height); const device = swapChain.getDevice(); + + return device; } diff --git a/examples/demos/webgpu/texture.ts b/examples/demos/webgpu/texture.ts deleted file mode 100644 index ab4b21cd4f7..00000000000 --- a/examples/demos/webgpu/texture.ts +++ /dev/null @@ -1,206 +0,0 @@ -import { - AddressMode, - BufferFrequencyHint, - BufferUsage, - FilterMode, - Format, - MipmapFilterMode, - TextureUsage, - TransparentWhite, - VertexStepMode, - WebGPUDeviceContribution, -} from '@antv/g-device-api'; -import { createTexture, generateTexture } from './utils/common'; -export async function MapRender(option: { map: string; renderer: 'regl' | 'device' }) { - const dom = document.getElementById('map') as HTMLDivElement; - // 创建 canvas - const $canvas = document.createElement('canvas'); - dom.appendChild($canvas); - // 设置 canvas 大小 - $canvas.width = dom.clientWidth; - $canvas.height = dom.clientHeight; - const deviceContribution = new WebGPUDeviceContribution({ - shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', - }); - const swapChain = await deviceContribution.createSwapChain($canvas); - swapChain.configureSwapChain($canvas.width, $canvas.height); - const device = swapChain.getDevice(); - const program = device.createProgram({ - vertex: { - entryPoint: 'main', - wgsl: ` - struct VertexOutput { - @location(1) uv: vec2, - @builtin(position) position : vec4, - - } - - - @vertex - fn main( - @location(0) pos: vec2f, - @location(1) uv: vec2 - ) -> VertexOutput { - var output : VertexOutput; - output.position = vec4(pos.xy, 0.0, 1.0); - output.uv = uv; - return output; - } - `, - }, - fragment: { - entryPoint: 'main', - wgsl: ` - @group(1) @binding(1) var mySampler: sampler; - @group(1) @binding(0) var myTexture: texture_2d;; - - @fragment - fn main( - @location(1) uv : vec2 - ) -> @location(0) vec4 { - return textureSample(myTexture, mySampler, uv); - } - `, - }, - }); - - async function loadImage(url) { - const img = new Image(); - const imgBitmap = await createImageBitmap(await fetch(url).then((response) => response.blob())); - return imgBitmap; - } - - // 创建纹理和纹理视图 - const url = - 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*p4PURaZpM-cAAAAAAAAAAAAADmJ7AQ/original'; - const texture = await generateTexture(device, url); - const numParticles = 6553600; - const particleRes = Math.ceil(Math.sqrt(numParticles)); - const numParticles2 = particleRes * particleRes; - const particleState = new Uint8ClampedArray(numParticles2 * 4); - for (let i = 0; i < particleState.length; i++) { - particleState[i] = Math.floor(Math.random() * 256); // randomize the initial particle positions - } - const particleStateTexture0 = await createTexture( - device, - particleRes, - particleRes, - particleState, - ); - - const sampler = device.createSampler({ - addressModeU: AddressMode.CLAMP_TO_EDGE, - addressModeV: AddressMode.CLAMP_TO_EDGE, - minFilter: FilterMode.POINT, - magFilter: FilterMode.BILINEAR, - mipmapFilter: MipmapFilterMode.LINEAR, - lodMinClamp: 0, - lodMaxClamp: 0, - }); - - const vertexBuffer = device.createBuffer({ - viewOrSize: new Float32Array([ - -1, - 1, - 0.0, - 1.0, // 左上角 - -1, - -1, - 0.0, - 0.0, // 左下角 - 1, - -1, - 1.0, - 0.0, // 右下角 - - // 第二个三角形 - 1, - 1, - 1.0, - 1.0, // 右上角 - ]), - usage: BufferUsage.VERTEX, - hint: BufferFrequencyHint.DYNAMIC, - }); - device.setResourceName(vertexBuffer, 'a_Position'); - const indexBuffer = device.createBuffer({ - viewOrSize: new Uint32Array([0, 1, 2, 0, 2, 3]), - usage: BufferUsage.INDEX, - hint: BufferFrequencyHint.STATIC, - }); - const inputLayout = device.createInputLayout({ - vertexBufferDescriptors: [ - { - arrayStride: 4 * 4, - stepMode: VertexStepMode.VERTEX, - attributes: [ - { - shaderLocation: 0, - offset: 0, - format: Format.F32_RG, - }, - { - shaderLocation: 1, - offset: 4 * 2, - format: Format.F32_RG, - }, - ], - }, - ], - indexBufferFormat: Format.U32_R, - program, - }); - - const pipeline = device.createRenderPipeline({ - inputLayout, - program, - colorAttachmentFormats: [Format.U8_RGBA_RT], - }); - - const bindings = device.createBindings({ - pipeline, - samplerBindings: [ - { - texture: particleStateTexture0, - sampler, - }, - ], - }); - - const renderTarget = device.createRenderTargetFromTexture( - device.createTexture({ - format: Format.U8_RGBA_RT, - width: $canvas.width, - height: $canvas.height, - usage: TextureUsage.RENDER_TARGET, - }), - ); - device.setResourceName(renderTarget, 'Main Render Target'); - - const onscreenTexture = swapChain.getOnscreenTexture(); - - const renderPass = device.createRenderPass({ - colorAttachment: [renderTarget], - colorResolveTo: [onscreenTexture], - colorClearColor: [TransparentWhite], - }); - - renderPass.setPipeline(pipeline); - renderPass.setVertexInput( - inputLayout, - [ - { - buffer: vertexBuffer, - }, - ], - { - buffer: indexBuffer, - offset: 0, - }, - ); - renderPass.setViewport(0, 0, $canvas.width, $canvas.height); - renderPass.setBindings(bindings); - renderPass.drawIndexed(6); - - device.submitPass(renderPass); -} diff --git a/examples/demos/webgpu/utils/common.ts b/examples/demos/webgpu/utils/common.ts index dcbb4c43d6b..4f8187a5373 100644 --- a/examples/demos/webgpu/utils/common.ts +++ b/examples/demos/webgpu/utils/common.ts @@ -1,10 +1,11 @@ import type { Device } from '@antv/g-device-api'; import { Format, TextureDimension, TextureUsage } from '@antv/g-device-api'; -async function loadImage(url) { +async function loadImage(url: string) { const imgBitmap = await createImageBitmap(await fetch(url).then((response) => response.blob())); return imgBitmap; } + export async function generateTexture(device: Device, url: string) { // 创建纹理和纹理视图 const image = await loadImage( diff --git a/examples/index.html b/examples/index.html index e4240c55244..1342845991f 100644 --- a/examples/index.html +++ b/examples/index.html @@ -8,19 +8,9 @@ /> L7: Preview - - - - - + + +
diff --git a/examples/app.tsx b/examples/index.tsx similarity index 76% rename from examples/app.tsx rename to examples/index.tsx index 28588e55613..9d193f1dc14 100644 --- a/examples/app.tsx +++ b/examples/index.tsx @@ -1,5 +1,5 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; -import MapView from './view'; +import { Main } from './main'; -ReactDOM.createRoot(document.getElementById('root')!).render(); +ReactDOM.createRoot(document.getElementById('root')!).render(
); diff --git a/examples/main.tsx b/examples/main.tsx new file mode 100644 index 00000000000..ce779b3fcdb --- /dev/null +++ b/examples/main.tsx @@ -0,0 +1,151 @@ +import type { Scene } from '@antv/l7-scene'; +import { Cascader, ConfigProvider } from 'antd'; +import 'antd/dist/reset.css'; +import type { Controller } from 'lil-gui'; +import GUI from 'lil-gui'; +import React, { useEffect, useRef, useState } from 'react'; +import { DEFAULT_GUI_OPTIONS, MAP_TYPES, SEARCH_PARAMS_KEYS } from './constants'; +import { TestCases } from './demos'; +import type { GUIOptions } from './types'; + +const DEMO_LIST = Array.from(TestCases).map(([namespace, cases]) => { + return { + label: namespace, + value: namespace, + children: cases.map(([name]) => ({ label: name, value: name })), + }; +}); + +const inintGuiOptions = getParamsFromUrlPath(); +const isSnapshotMode = inintGuiOptions.snapshot; + +export const Main = () => { + const guiRef = useRef(); + const mapContainer = useRef(null); + const [guiOptions, setGuiOptions] = useState(inintGuiOptions); + const [viewDemo, setViewDemo] = useState<[string, string]>(() => { + const { namespace = 'point', name = 'fill' } = inintGuiOptions; + return [namespace, name]; + }); + + // GUI + useEffect(() => { + guiRef.current = new GUI({ title: 'Scene', autoPlace: !isSnapshotMode }); + const onChange = (v: Partial) => { + setGuiOptions((pre) => ({ ...pre, ...v })); + }; + guiRef.current + .add(inintGuiOptions, 'map', MAP_TYPES) + .onChange((map: GUIOptions['map']) => onChange({ map })); + guiRef.current + .add(inintGuiOptions, 'renderer', ['regl', 'device']) + .onChange((renderer: GUIOptions['renderer']) => onChange({ renderer })); + guiRef.current + .add(inintGuiOptions, 'enableWebGPU') + .onChange((enableWebGPU: GUIOptions['enableWebGPU']) => onChange({ enableWebGPU })); + guiRef.current + .add(inintGuiOptions, 'animate') + .onChange((animate: GUIOptions['animate']) => onChange({ animate })); + + return () => { + guiRef.current?.destroy(); + }; + }, []); + + // change TestCase + useEffect(() => { + const [namespace, name] = viewDemo; + const TestCase = getDemoFromName(namespace, name); + if (!TestCase) return; + + let scene: Scene; + let extendGUI: Controller[] | GUI[] = []; + + const asyncFun = async () => { + scene = await TestCase({ ...guiOptions, id: mapContainer.current! }); + if (TestCase.extendGUI) { + extendGUI = TestCase.extendGUI?.(guiRef.current!); + } + + // @ts-ignore + if (isSnapshotMode && window.screenshot) { + // @ts-ignore + await window.screenshot(); + } + }; + + asyncFun(); + syncParamsToURLPath({ ...guiOptions, namespace, name }); + + return () => { + scene?.destroy(); + while (mapContainer.current?.firstChild) { + mapContainer.current.removeChild(mapContainer.current.lastChild!); + } + try { + extendGUI.forEach((d) => d.destroy()); + } catch (error) { + console.warn('error: ', error); + } + }; + }, [viewDemo, guiOptions]); + + const onDemoViewChange = (value: string[]) => { + setViewDemo(value as [string, string]); + }; + + return ( + <> + {!isSnapshotMode && ( + + + + )} +
+ + ); +}; + +/** + * get guiOptions(SEARCH_PARAMS_KEYS) from URL path + * @returns + */ +function getParamsFromUrlPath() { + const guiOptions = { + ...DEFAULT_GUI_OPTIONS, + }; + const searchParams = new URLSearchParams(window.location.search); + + SEARCH_PARAMS_KEYS.forEach((key) => { + const value = searchParams.get(key); + if (!value) return; + if (['animate', 'snapshot', 'enableWebGPU'].includes(key)) guiOptions[key] = value === 'true'; + else guiOptions[key] = value; + }); + + return guiOptions; +} + +/** + * sync guiOptions(SEARCH_PARAMS_KEYS) to URL path + */ +function syncParamsToURLPath(guiOptions: GUIOptions) { + const searchParams = new URLSearchParams(window.location.search); + Object.entries(guiOptions).forEach(([key, value]) => { + if (SEARCH_PARAMS_KEYS.includes(key as (typeof SEARCH_PARAMS_KEYS)[number])) { + searchParams.set(key, value.toString()); + } + }); + window.history.replaceState(null, '', `?${searchParams.toString()}`); +} + +function getDemoFromName(namespace: string, name: string) { + const demo = TestCases.get(namespace)?.find(([_name]) => _name === name)?.[1]; + return demo; +} diff --git a/examples/types.ts b/examples/types.ts index 6c3ff45f5eb..bf5cd325dba 100644 --- a/examples/types.ts +++ b/examples/types.ts @@ -1,6 +1,16 @@ +import type { Scene } from '@antv/l7'; import type { ISceneConfig } from '@antv/l7-core'; +import type { Controller, GUI } from 'lil-gui'; -export type RenderDemoMap = +export type GUIOptions = { + map: TestCaseBasemap; + renderer: ISceneConfig['renderer']; + animate: boolean; + enableWebGPU: boolean; + [keys: string]: any; +}; + +export type TestCaseBasemap = | 'Map' | 'GaodeMap' | 'BaiduMap' @@ -10,8 +20,11 @@ export type RenderDemoMap = | 'TMap' | 'GoogleMap'; -export type RenderDemoOptions = { - map: RenderDemoMap; - renderer: ISceneConfig['renderer']; - animate: boolean; +export type TestCaseOptions = GUIOptions & { + id: string | HTMLDivElement; +}; + +export type TestCase = { + (options: TestCaseOptions): Promise; + extendGUI?: (gui: GUI) => Controller[] | GUI[]; }; diff --git a/examples/utils/index.ts b/examples/utils/index.ts new file mode 100644 index 00000000000..53294eeee79 --- /dev/null +++ b/examples/utils/index.ts @@ -0,0 +1,2 @@ +export * from './scene'; +export * from './sleep'; diff --git a/examples/utils/scene.ts b/examples/utils/scene.ts new file mode 100644 index 00000000000..96fe9f6d43b --- /dev/null +++ b/examples/utils/scene.ts @@ -0,0 +1,41 @@ +import { Scene } from '@antv/l7'; +import type { IMapConfig } from '@antv/l7-core'; +import * as Maps from '@antv/l7-maps'; +import type { TestCaseOptions } from '../types'; + +type CaseSceneOptions = TestCaseOptions & { + mapConfig?: Partial; +}; + +export const CaseScene = (options: CaseSceneOptions) => { + const { map: basemap, animate, mapConfig } = options; + + const isMapbox = ['MapLibre', 'Mapbox'].includes(basemap); + + const style = isMapbox + ? 'https://basemaps.cartocdn.com/gl/positron-nolabels-gl-style/style.json' + : 'light'; + + const map = new Maps[basemap]({ + style, + center: [120.188193, 30.292542], + rotation: 0, + pitch: 0, + zoom: 16, + ...mapConfig, + }); + + const scene = new Scene({ + ...options, + map, + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', + logoVisible: false, + }); + + return new Promise((resolve) => { + scene.on('loaded', () => { + animate && scene.startAnimate(); + resolve(scene); + }); + }); +}; diff --git a/examples/view.tsx b/examples/view.tsx deleted file mode 100644 index 5f5eb7d39f3..00000000000 --- a/examples/view.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import { Cascader } from 'antd'; -import 'antd/dist/reset.css'; -import GUI from 'lil-gui'; -import React, { useEffect, useState } from 'react'; -import { DEFAULT_RENDER_OPTIONS, MAP_TYPES } from './constants'; -import DemoList from './demos'; -import { MapView } from './view/map'; - -export default () => { - const searchParams = new URL(location as any).searchParams; - const initState = - searchParams.size === 0 - ? ['Point', 'fill'] - : [searchParams.get('type'), searchParams.get('name')]; - const [values, setValue] = useState(initState); - const [mapOption, setMapOption] = useState(DEFAULT_RENDER_OPTIONS); - const onGUIChange = (object: any) => { - setMapOption({ ...object }); - }; - useEffect(() => { - const gui = new GUI(); - const option = { - map: 'Map', - renderer: 'device', - animate: false, - }; - gui.add(option, 'map', MAP_TYPES); - gui.add(option, 'renderer', ['regl', 'device']); - gui.add(option, 'animate'); - gui.onChange((event) => { - onGUIChange(event.object); - }); - }, []); - - const CascaderOption = DemoList.map((group) => { - return { - label: group.name, - value: group.name, - children: Object.keys(group.demos).map((key) => { - return { - label: key, - value: key, - demo: group.demos[key], - }; - }), - }; - }); - - const onChange = (e: any) => { - history.pushState({ value: e }, '', `?type=${e[0]}&name=${e[1]}`); - setValue(e); - }; - return ( - <> -
- -
- - {/* 不同 Demo 可替换 view 模板 */} - - - ); -}; diff --git a/examples/view/map.tsx b/examples/view/map.tsx deleted file mode 100644 index 1e2b33e64bf..00000000000 --- a/examples/view/map.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React, { useEffect } from 'react'; -import DemoList from '../demos'; -export const MapView = (props) => { - const { data = ['Point', 'fill'], options } = props; // 通过解构赋值获取传递的 data 参数 - useEffect(() => { - const group = DemoList.find((d) => d.name === data[0]); - group?.demos[data[1]](options); - return () => { - const mapElement = document.getElementById('map'); - if (mapElement) { - mapElement.innerHTML = ''; - } - }; - }, [data, options]); - - return
; -}; diff --git a/package.json b/package.json index c65132c66bb..9e88de448fa 100644 --- a/package.json +++ b/package.json @@ -65,10 +65,12 @@ "geotiff": "^2.0.1", "kdbush": "^4.0.2", "lil-gui": "^0.19.1", + "maplibre-gl": "^3.5.2", "pmtiles": "^2.7.2", "react": "^18.2.0", "react-dom": "^18.2.0", - "stats.js": "^0.17.0" + "stats.js": "^0.17.0", + "three": "0.115.0" }, "devDependencies": { "@antv/translator": "^1.0.1", diff --git a/packages/component/CHANGELOG.md b/packages/component/CHANGELOG.md index ca0917a29e4..01a6a5cfff5 100644 --- a/packages/component/CHANGELOG.md +++ b/packages/component/CHANGELOG.md @@ -1,5 +1,79 @@ # Change Log +## 2.21.11-beta.7 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-layers@2.21.11-beta.7 + - @antv/l7-core@2.21.11-beta.7 + - @antv/l7-utils@2.21.11-beta.7 + +## 2.21.11-beta.6 + +### Patch Changes + +- Updated dependencies [[`67647e9`](https://github.com/antvis/L7/commit/67647e95c5b06b593604310c78c6a0ec195c3a01)]: + - @antv/l7-layers@2.21.11-beta.6 + - @antv/l7-core@2.21.11-beta.6 + - @antv/l7-utils@2.21.11-beta.6 + +## 2.21.11-beta.5 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-layers@2.21.11-beta.5 + - @antv/l7-core@2.21.11-beta.5 + - @antv/l7-utils@2.21.11-beta.5 + +## 2.21.11-beta.4 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-layers@2.21.11-beta.4 + - @antv/l7-core@2.21.11-beta.4 + - @antv/l7-utils@2.21.11-beta.4 + +## 2.21.11-beta.3 + +### Patch Changes + +- [#2509](https://github.com/antvis/L7/pull/2509) [`aca779d`](https://github.com/antvis/L7/commit/aca779dac55ebf9ee1116106d69e71bb872b4ccc) Thanks [@lvisei](https://github.com/lvisei)! - fix: 无地图与 MapLibre 模式移动 Marker 出错 + +- Updated dependencies [[`a5f57ed`](https://github.com/antvis/L7/commit/a5f57eda52dab160fe076f252ad52cd51b8f456a)]: + - @antv/l7-core@2.21.11-beta.3 + - @antv/l7-layers@2.21.11-beta.3 + - @antv/l7-utils@2.21.11-beta.3 + +## 2.21.11-beta.2 + +### Patch Changes + +- Updated dependencies [[`0754eeb`](https://github.com/antvis/L7/commit/0754eebe5c029c808958a5f29492ed2487263c7f)]: + - @antv/l7-layers@2.21.11-beta.2 + - @antv/l7-core@2.21.11-beta.2 + - @antv/l7-utils@2.21.11-beta.2 + +## 2.21.11-beta.1 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-layers@2.21.11-beta.1 + - @antv/l7-core@2.21.11-beta.1 + - @antv/l7-utils@2.21.11-beta.1 + +## 2.21.11-beta.0 + +### Patch Changes + +- Updated dependencies [[`3e33888`](https://github.com/antvis/L7/commit/3e33888a56c6efa80be60bc79182644eaccaa500), [`d408bdb`](https://github.com/antvis/L7/commit/d408bdb4a2a7be57a50f9a88247cf7b690ba4387)]: + - @antv/l7-layers@2.21.11-beta.0 + - @antv/l7-core@2.21.11-beta.0 + - @antv/l7-utils@2.21.11-beta.0 + ## 2.21.10 ### Patch Changes diff --git a/packages/component/package.json b/packages/component/package.json index 35bfb39f2b3..286ebb370d2 100644 --- a/packages/component/package.json +++ b/packages/component/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7-component", - "version": "2.21.10", + "version": "2.21.11-beta.7", "description": "Component for L7", "license": "MIT", "author": "https://github.com/orgs/antvis/people", diff --git a/packages/component/src/control/mouseLocation.ts b/packages/component/src/control/mouseLocation.ts index e8c16c6bc0c..1f2ebe76a53 100644 --- a/packages/component/src/control/mouseLocation.ts +++ b/packages/component/src/control/mouseLocation.ts @@ -39,6 +39,7 @@ export default class MouseLocation extends Control } protected onMouseMove = (e: any) => { let position: Position = this.location; + // 适配不同底图,事件返回的数据名称不一致 const lngLat: ILngLat | undefined = e.lngLat || e.lnglat; const { transform } = this.controlOption; if (lngLat) { diff --git a/packages/component/src/marker.ts b/packages/component/src/marker.ts index ee1be5a4dcb..33e37363e77 100644 --- a/packages/component/src/marker.ts +++ b/packages/component/src/marker.ts @@ -295,14 +295,16 @@ export default class Marker extends EventEmitter { }; private onMarkerDragMove = (e: any) => { + // 适配不同底图,事件返回的数据名称不一致 + const lngLat: ILngLat = e.lngLat || e.lnglat; const { lng: preLng, lat: preLat } = this.preLngLat; - const { lng: curLng, lat: curLat } = e.lnglat; + const { lng: curLng, lat: curLat } = lngLat; const newLngLat = { lng: this.lngLat.lng + curLng - preLng, lat: this.lngLat.lat + curLat - preLat, }; this.setLnglat(newLngLat); - this.preLngLat = e.lnglat; + this.preLngLat = lngLat; this.emit('dragging', newLngLat); }; @@ -435,7 +437,7 @@ export default class Marker extends EventEmitter { */ private touchStartTime: number; private polyfillEvent(e: MouseEvent | TouchEvent) { - if (!this.mapsService || this.mapsService.version !== 'GAODE2.x') { + if (!this.mapsService || this.mapsService.getType() !== 'amap') { return; } if (!isPC()) { diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 5d311078ed9..a8cee03f192 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,63 @@ # Change Log +## 2.21.11-beta.7 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-utils@2.21.11-beta.7 + +## 2.21.11-beta.6 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-utils@2.21.11-beta.6 + +## 2.21.11-beta.5 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-utils@2.21.11-beta.5 + +## 2.21.11-beta.4 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-utils@2.21.11-beta.4 + +## 2.21.11-beta.3 + +### Patch Changes + +- [#2511](https://github.com/antvis/L7/pull/2511) [`a5f57ed`](https://github.com/antvis/L7/commit/a5f57eda52dab160fe076f252ad52cd51b8f456a) Thanks [@lvisei](https://github.com/lvisei)! - fix: 在 WebGL2 拾取事件冒泡延迟问题 + +- Updated dependencies []: + - @antv/l7-utils@2.21.11-beta.3 + +## 2.21.11-beta.2 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-utils@2.21.11-beta.2 + +## 2.21.11-beta.1 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-utils@2.21.11-beta.1 + +## 2.21.11-beta.0 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-utils@2.21.11-beta.0 + ## 2.21.10 ### Patch Changes diff --git a/packages/core/package.json b/packages/core/package.json index 3a3e8a8346f..d5bb7afd396 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7-core", - "version": "2.21.10", + "version": "2.21.11-beta.7", "description": "", "license": "MIT", "author": "https://github.com/orgs/antvis/people", diff --git a/packages/core/src/services/coordinate/CoordinateSystemService.ts b/packages/core/src/services/coordinate/CoordinateSystemService.ts index a37ff05fc16..69ba155a9d0 100644 --- a/packages/core/src/services/coordinate/CoordinateSystemService.ts +++ b/packages/core/src/services/coordinate/CoordinateSystemService.ts @@ -16,7 +16,6 @@ export default class CoordinateSystemService implements ICoordinateSystemService * 2. 偏移经纬度,用于解决高精度抖动问题 * 3. 瓦片坐标,用于数据瓦片 * 4. 常规世界坐标系,用于常规 2D/3D 可视化场景 - * 5. P20 坐标系,高德地图使用 * @see https://yuque.antfin-inc.com/yuqi.pyq/fgetpa/doml91 */ private coordinateSystem: CoordinateSystem; @@ -58,7 +57,6 @@ export default class CoordinateSystemService implements ICoordinateSystemService // return; // } const zoom = this.cameraService.getZoom(); - const zoomScale = this.cameraService.getZoomScale(); const center = offsetCenter ? offsetCenter : this.cameraService.getCenter(); // 计算像素到米以及经纬度之间的转换 @@ -73,16 +71,11 @@ export default class CoordinateSystemService implements ICoordinateSystemService this.pixelsPerDegree = pixelsPerDegree; this.pixelsPerDegree2 = [0, 0, 0]; - if ( - this.coordinateSystem === CoordinateSystem.LNGLAT || - this.coordinateSystem === CoordinateSystem.P20 - ) { + if (this.coordinateSystem === CoordinateSystem.LNGLAT) { // 继续使用相机服务计算的 VP 矩阵 this.cameraService.setViewProjectionMatrix(undefined); } else if (this.coordinateSystem === CoordinateSystem.LNGLAT_OFFSET) { this.calculateLnglatOffset(center, zoom); - } else if (this.coordinateSystem === CoordinateSystem.P20_OFFSET) { - this.calculateLnglatOffset(center, zoom, zoomScale, true); } this.needRefresh = false; diff --git a/packages/core/src/services/coordinate/ICoordinateSystemService.ts b/packages/core/src/services/coordinate/ICoordinateSystemService.ts index 2a71a06b425..671f533378a 100644 --- a/packages/core/src/services/coordinate/ICoordinateSystemService.ts +++ b/packages/core/src/services/coordinate/ICoordinateSystemService.ts @@ -4,7 +4,6 @@ * 2. 偏移经纬度,用于解决高精度抖动问题 * 3. 瓦片坐标,用于数据瓦片 * 4. 常规世界坐标系,用于常规 2D/3D 可视化场景 - * 5. P20 * @see https://yuque.antfin-inc.com/yuqi.pyq/fgetpa/doml91 */ @@ -14,10 +13,7 @@ export enum CoordinateSystem { LNGLAT_OFFSET = 2.0, VECTOR_TILE = 3.0, IDENTITY = 4.0, - P20 = 5.0, - P20_OFFSET = 6.0, - METER_OFFSET = 7.0, - P20_2 = 8.0, + METER_OFFSET = 5.0, } // 后续传入 Shader 的变量 @@ -28,8 +24,6 @@ export const CoordinateUniform = { PixelsPerDegree: 'u_PixelsPerDegree', PixelsPerDegree2: 'u_PixelsPerDegree2', PixelsPerMeter: 'u_PixelsPerMeter', - - Mvp: 'u_Mvp', }; export interface ICoordinateSystemService { diff --git a/packages/core/src/services/interaction/PickingService.ts b/packages/core/src/services/interaction/PickingService.ts index 9a800de4de2..9090c42b6eb 100644 --- a/packages/core/src/services/interaction/PickingService.ts +++ b/packages/core/src/services/interaction/PickingService.ts @@ -147,9 +147,9 @@ export default class PickingService implements IPickingService { public handleCursor(layer: ILayer, type: string) { const { cursor = '', cursorEnabled } = layer.getLayerConfig(); if (cursorEnabled) { - const version = this.mapService.version; + const mapType = this.mapService.getType(); const domContainer = - version === 'GAODE2.x' + mapType === 'amap' ? this.mapService.getMapContainer() : this.mapService.getMarkerContainer(); // const domContainer = this.mapService.getMarkerContainer(); @@ -177,7 +177,7 @@ export default class PickingService implements IPickingService { { x, y, lngLat, type, target }: IInteractionTarget, ) => { let isPicked = false; - const { readPixelsAsync, getViewportSize } = this.rendererService; + const { readPixels, readPixelsAsync, getViewportSize, queryVerdorInfo } = this.rendererService; const { width, height } = getViewportSize(); const { enableHighlight, enableSelect } = layer.getLayerConfig(); const xInDevicePixel = x * DOM.DPR; @@ -190,15 +190,33 @@ export default class PickingService implements IPickingService { ) { return false; } - const pickedColors: Uint8Array | undefined = await readPixelsAsync({ - x: Math.floor(xInDevicePixel / this.pickBufferScale), - // 视口坐标系原点在左上,而 WebGL 在左下,需要翻转 Y 轴 - y: Math.floor((height - (y + 1) * DOM.DPR) / this.pickBufferScale), - width: 1, - height: 1, - data: new Uint8Array(1 * 1 * 4), - framebuffer: this.pickingFBO, - }); + + let pickedColors: Uint8Array | undefined; + + // readPixelsAsync 比 readPixels 慢,会造成拾取事件冒泡延迟,优先使用 readPixelsAsync,WebGPU 只支持 readPixelsAsync API + const isWebGPU = queryVerdorInfo() === 'WebGPU'; + if (isWebGPU) { + pickedColors = await readPixelsAsync({ + x: Math.floor(xInDevicePixel / this.pickBufferScale), + // 视口坐标系原点在左上,而 WebGL 在左下,需要翻转 Y 轴 + y: Math.floor((height - (y + 1) * DOM.DPR) / this.pickBufferScale), + width: 1, + height: 1, + data: new Uint8Array(1 * 1 * 4), + framebuffer: this.pickingFBO, + }); + } else { + pickedColors = readPixels({ + x: Math.floor(xInDevicePixel / this.pickBufferScale), + // 视口坐标系原点在左上,而 WebGL 在左下,需要翻转 Y 轴 + y: Math.floor((height - (y + 1) * DOM.DPR) / this.pickBufferScale), + width: 1, + height: 1, + data: new Uint8Array(1 * 1 * 4), + framebuffer: this.pickingFBO, + }); + } + this.pickedColors = pickedColors; if (pickedColors[0] !== 0 || pickedColors[1] !== 0 || pickedColors[2] !== 0) { diff --git a/packages/core/src/services/layer/ILayerService.ts b/packages/core/src/services/layer/ILayerService.ts index 3ace2441b85..399beec7464 100644 --- a/packages/core/src/services/layer/ILayerService.ts +++ b/packages/core/src/services/layer/ILayerService.ts @@ -1,4 +1,3 @@ -// @ts-ignore import type { AsyncSeriesBailHook, AsyncWaterfallHook, @@ -29,6 +28,7 @@ import type { import type { IRendererService } from '../renderer/IRendererService'; import type { ITexture2D } from '../renderer/ITexture2D'; import type { IUniform } from '../renderer/IUniform'; +import type { ShaderDefine, ShaderInject } from '../shader/IShaderModuleService'; import type { IParseDataItem, ISource, ISourceCFG, ITransform } from '../source/ISourceService'; import type { IAnimateOption, @@ -73,6 +73,10 @@ export interface ILayerModelInitializationOptions { moduleName: string; vertexShader: string; fragmentShader: string; + /** Code injections */ + inject?: ShaderInject; + /** Defines to be injected */ + defines?: Record; triangulation: Triangulation; styleOption?: unknown; workerEnabled?: boolean; @@ -572,11 +576,6 @@ export interface ILayer { // 设置当前地球时间 控制太阳角度 setEarthTime(time: number): void; - /** - * WebGL2 下更新 Layer 级 Uniform - */ - getLayerUniformBuffer(): IBuffer; - /** * WebGL2 下更新 Layer 级 Uniform */ diff --git a/packages/core/src/services/layer/LayerService.ts b/packages/core/src/services/layer/LayerService.ts index 376cd36053d..1fb2bc4a133 100644 --- a/packages/core/src/services/layer/LayerService.ts +++ b/packages/core/src/services/layer/LayerService.ts @@ -1,3 +1,4 @@ +import type { DebouncedFunc } from '@antv/l7-utils'; import { lodashUtil, rgb2arr } from '@antv/l7-utils'; import { EventEmitter } from 'eventemitter3'; import type { L7Container } from '../../inversify.config'; @@ -42,11 +43,11 @@ export default class LayerService extends EventEmitter implem super(); } - public reRender = throttle(() => { + public reRender: DebouncedFunc<() => void> = throttle(() => { this.renderLayers(); }, 32); - public throttleRenderLayers = throttle(() => { + public throttleRenderLayers: DebouncedFunc<() => void> = throttle(() => { this.renderLayers(); }, 16); diff --git a/packages/core/src/services/map/IMapService.ts b/packages/core/src/services/map/IMapService.ts index 4897bd5078e..8d0789bd584 100644 --- a/packages/core/src/services/map/IMapService.ts +++ b/packages/core/src/services/map/IMapService.ts @@ -34,11 +34,7 @@ export type MapStyleConfig = { export type MapStyle = MapStyleName | any; export interface IMapWrapper { - setContainer( - container: L7Container, - id: string | HTMLDivElement, - canvas?: HTMLCanvasElement, - ): void; + setContainer(container: L7Container, id: string | HTMLDivElement): void; } interface ISimpleMapCoord { @@ -53,7 +49,6 @@ export interface IMapService { simpleMapCoord: ISimpleMapCoord; map: RawMap; bgColor: string; - setCoordCenter?(center: number[]): void; setBgColor(color: string): void; init(): void; initMiniMap?(): void; @@ -122,7 +117,6 @@ export interface IMapService { lnglatArray: number[][][] | number[][], ): number[][][] | number[][] | number[][][] | number[][]; // lngLatToCoords?(lnglatArray: any): any; - getCustomCoordCenter?(): [number, number]; exportMap(type: 'jpg' | 'png'): string; // 地球模式下的地图方法/属性 @@ -311,8 +305,6 @@ export interface IMapCamera { cameraPosition?: [number, number, number]; up?: [number, number, number]; lookAt?: [number, number, number]; - // 偏移原点,例如 P20 坐标系下 - offsetOrigin: [number, number]; } export interface ICameraOptions { padding: diff --git a/packages/core/src/services/renderer/IModel.ts b/packages/core/src/services/renderer/IModel.ts index 9a256e96eac..8d0c9f6d3d8 100644 --- a/packages/core/src/services/renderer/IModel.ts +++ b/packages/core/src/services/renderer/IModel.ts @@ -128,14 +128,7 @@ type BlendingFunctionSeparate = Partial<{ | gl.SRC_ALPHA_SATURATE; dstAlpha: number; }>; -export type injectType = - | 'vs:#decl' - | 'vs:#main-start' - | 'vs:#main-end' - | 'fs:#decl' - | 'fs:#main-start' - | 'fs:#main-end'; -export type IInject = Partial>; + export interface IModelInitializationOptions { /** * 该 model 是否支持拾取 @@ -147,8 +140,6 @@ export interface IModelInitializationOptions { vs: string; fs: string; - inject?: IInject; - uniforms?: { [key: string]: IUniform; }; diff --git a/packages/core/src/services/renderer/passes/PixelPickingPass.ts b/packages/core/src/services/renderer/passes/PixelPickingPass.ts index d46ade8555d..750b6d3c7cc 100644 --- a/packages/core/src/services/renderer/passes/PixelPickingPass.ts +++ b/packages/core/src/services/renderer/passes/PixelPickingPass.ts @@ -11,6 +11,8 @@ import BaseNormalPass from './BaseNormalPass'; /** * color-based PixelPickingPass * @see https://github.com/antvis/L7/blob/next/dev-docs/PixelPickingEngine.md + * @deprecated + * 目前未使用 */ export default class PixelPickingPass< InitializationOptions = {}, diff --git a/packages/core/src/services/renderer/passes/PostProcessor.ts b/packages/core/src/services/renderer/passes/PostProcessor.ts index b08a8533592..e16e5ceacc8 100644 --- a/packages/core/src/services/renderer/passes/PostProcessor.ts +++ b/packages/core/src/services/renderer/passes/PostProcessor.ts @@ -3,6 +3,7 @@ import type { IFramebuffer } from '../IFramebuffer'; import type { IPostProcessingPass, IPostProcessor } from '../IMultiPassRenderer'; import type { IRendererService } from '../IRendererService'; import type { ITexture2D } from '../ITexture2D'; +import { TextureUsage } from '../ITexture2D'; import { gl } from '../gl'; /** @@ -127,6 +128,7 @@ export default class PostProcessor implements IPostProcessor { height: 1, wrapS: gl.CLAMP_TO_EDGE, wrapT: gl.CLAMP_TO_EDGE, + usage: TextureUsage.RENDER_TARGET, }), }); this.writeFBO = createFramebuffer({ @@ -135,6 +137,7 @@ export default class PostProcessor implements IPostProcessor { height: 1, wrapS: gl.CLAMP_TO_EDGE, wrapT: gl.CLAMP_TO_EDGE, + usage: TextureUsage.RENDER_TARGET, }), }); } diff --git a/packages/core/src/services/scene/SceneService.ts b/packages/core/src/services/scene/SceneService.ts index 45d4baea7c4..725f226459e 100644 --- a/packages/core/src/services/scene/SceneService.ts +++ b/packages/core/src/services/scene/SceneService.ts @@ -180,7 +180,10 @@ export default class Scene extends EventEmitter implements ISceneService { // 创建底图之上的 container if (this.$container) { - this.canvas = DOM.create('canvas', '', this.$container) as HTMLCanvasElement; + const { canvas } = sceneConfig; + this.canvas = canvas + ? canvas + : (DOM.create('canvas', '', this.$container) as HTMLCanvasElement); this.setCanvas(); await this.rendererService.init( // @ts-ignore diff --git a/packages/core/src/services/shader/IShaderModuleService.ts b/packages/core/src/services/shader/IShaderModuleService.ts index 35f97be07d0..deef199bb38 100644 --- a/packages/core/src/services/shader/IShaderModuleService.ts +++ b/packages/core/src/services/shader/IShaderModuleService.ts @@ -1,6 +1,17 @@ -import type { IInject } from '../renderer/IModel'; import type { IUniform } from '../renderer/IUniform'; +export type ShaderInjectType = + | 'vs:#decl' + | 'vs:#main-start' + | 'vs:#main-end' + | 'fs:#decl' + | 'fs:#main-start' + | 'fs:#main-end'; + +export type ShaderInject = Partial>; + +export type ShaderDefine = string | number | boolean; + /** * 提供 ShaderModule 管理服务 */ @@ -11,7 +22,10 @@ export interface IModuleParams { uniforms?: { [key: string]: IUniform; }; - inject?: IInject; + /** Code injections */ + inject?: ShaderInject; + /** Defines to be injected */ + defines?: Record; } export interface IShaderModuleService { diff --git a/packages/core/src/services/shader/ShaderModuleService.ts b/packages/core/src/services/shader/ShaderModuleService.ts index 4954bb9de40..bf43bbb7878 100644 --- a/packages/core/src/services/shader/ShaderModuleService.ts +++ b/packages/core/src/services/shader/ShaderModuleService.ts @@ -1,6 +1,6 @@ import { lodashUtil } from '@antv/l7-utils'; import { extractUniforms } from '../../utils/shader-module'; -import type { IModuleParams, IShaderModuleService } from './IShaderModuleService'; +import type { IModuleParams, IShaderModuleService, ShaderDefine } from './IShaderModuleService'; const { uniq } = lodashUtil; import common from '../../shaders/common.glsl'; @@ -15,6 +15,7 @@ import projection from '../../shaders/projection.glsl'; import rotation_2d from '../../shaders/rotation_2d.glsl'; import scene_uniforms from '../../shaders/scene_uniforms.glsl'; import sdf2d from '../../shaders/sdf_2d.glsl'; + const precisionRegExp = /precision\s+(high|low|medium)p\s+float/; const globalDefaultprecision = '#ifdef GL_FRAGMENT_PRECISION_HIGH\n precision highp float;\n #else\n precision mediump float;\n#endif\n'; @@ -29,14 +30,8 @@ export default class ShaderModuleService implements IShaderModuleService { this.destroy(); this.registerModule('common', { vs: common, fs: common }); this.registerModule('decode', { vs: decode, fs: '' }); - this.registerModule('scene_uniforms', { - vs: scene_uniforms, - fs: scene_uniforms, - }); - this.registerModule('picking_uniforms', { - vs: picking_uniforms, - fs: picking_uniforms, - }); + this.registerModule('scene_uniforms', { vs: scene_uniforms, fs: scene_uniforms }); + this.registerModule('picking_uniforms', { vs: picking_uniforms, fs: picking_uniforms }); this.registerModule('projection', { vs: projection, fs: projection }); this.registerModule('project', { vs: project, fs: '' }); @@ -55,11 +50,13 @@ export default class ShaderModuleService implements IShaderModuleService { moduleParams.vs = moduleParams.vs.replace(/\r\n/g, '\n'); // 将所有的\r\n替换为\n moduleParams.fs = moduleParams.fs.replace(/\r\n/g, '\n'); // 将所有的\r\n替换为\n - const { vs, fs, uniforms: declaredUniforms, inject } = moduleParams; + const { vs, fs, uniforms: declaredUniforms, defines, inject } = moduleParams; const { content: extractedVS, uniforms: vsUniforms } = extractUniforms(vs); const { content: extractedFS, uniforms: fsUniforms } = extractUniforms(fs); + this.rawContentCache[moduleName] = { fs: extractedFS, + defines, inject, uniforms: { ...vsUniforms, @@ -69,10 +66,7 @@ export default class ShaderModuleService implements IShaderModuleService { vs: extractedVS, }; } - public destroy() { - this.moduleCache = {}; - this.rawContentCache = {}; - } + public getModule(moduleName: string): IModuleParams { // TODO: cache module // if (this.moduleCache[moduleName]) { @@ -81,27 +75,36 @@ export default class ShaderModuleService implements IShaderModuleService { let rawVS = this.rawContentCache[moduleName].vs; let rawFS = this.rawContentCache[moduleName].fs; - const inject = this.rawContentCache[moduleName].inject; + const { defines = {}, inject = {} } = this.rawContentCache[moduleName]; + let declaredUniforms = {}; - if (inject?.['vs:#decl']) { - // 头部注入 - rawVS = inject?.['vs:#decl'] + rawVS; - declaredUniforms = extractUniforms(inject?.['vs:#decl']).uniforms; + + // vs 头部注入 + if (inject['vs:#decl']) { + rawVS = inject['vs:#decl'] + rawVS; + declaredUniforms = extractUniforms(inject['vs:#decl']).uniforms; } - if (inject?.['vs:#main-start']) { - // main + + // vs main + if (inject['vs:#main-start']) { rawVS = rawVS.replace(REGEX_START_OF_MAIN, (match: string) => { - return match + inject?.['vs:#main-start']; + return match + inject['vs:#main-start']; }); } - if (inject?.['fs:#decl']) { - // 头部注入 - rawFS = inject?.['fs:#decl'] + rawFS; + + // fs 头部注入 + if (inject['fs:#decl']) { + rawFS = inject['fs:#decl'] + rawFS; } + const injectDefines = getInjectDefines(defines); + + // 注入定义的宏 + rawVS = injectDefines + rawVS; + const { content: vs, includeList: vsIncludeList } = this.processModule(rawVS, [], 'vs'); const { content: fs, includeList: fsIncludeList } = this.processModule(rawFS, [], 'fs'); - let compiledFs = ''; + // TODO: extract uniforms and their default values from GLSL const uniforms: { [key: string]: any; @@ -121,25 +124,28 @@ export default class ShaderModuleService implements IShaderModuleService { * set default precision for fragment shader * https://stackoverflow.com/questions/28540290/why-it-is-necessary-to-set-precision-for-the-fragment-shader */ - if (!precisionRegExp.test(fs)) { - compiledFs = compiledFs + globalDefaultprecision; - } - compiledFs = compiledFs + fs; - - let compiledVs = ''; - if (!precisionRegExp.test(vs)) { - compiledVs = compiledVs + globalDefaultprecision; - } - compiledVs = compiledVs + vs; + const compiledVs = (precisionRegExp.test(fs) ? '' : globalDefaultprecision) + vs; + const compiledFs = (precisionRegExp.test(fs) ? '' : globalDefaultprecision) + fs; this.moduleCache[moduleName] = { + vs: compiledVs.trim(), fs: compiledFs.trim(), uniforms, - vs: compiledVs.trim(), }; + return this.moduleCache[moduleName]; } + public destroy() { + this.moduleCache = {}; + this.rawContentCache = {}; + } + + /** + * + * 解析定义的内联模块 + * like: #pragma include "projection" + */ private processModule( rawContent: string, includeList: string[], @@ -169,11 +175,12 @@ export default class ShaderModuleService implements IShaderModuleService { includeList, }; } +} - private injectDefines(defines: Record) { - const defineStr = Object.keys(defines).reduce((prev, cur) => { - return prev + `#define ${cur.toUpperCase()} ${defines[cur]};\n`; - }, '\n'); - return defineStr; - } +/** Generates defines from an object of key value pairs */ +function getInjectDefines(defines: Record) { + const defineStr = Object.keys(defines).reduce((prev, cur) => { + return prev + `#define ${cur.toUpperCase()} ${defines[cur]}\n`; + }, '\n'); + return defineStr; } diff --git a/packages/core/src/shaders/picking.vert.glsl b/packages/core/src/shaders/picking.vert.glsl index c987c7b7c6a..f58bc32f540 100644 --- a/packages/core/src/shaders/picking.vert.glsl +++ b/packages/core/src/shaders/picking.vert.glsl @@ -1,4 +1,4 @@ -layout(location = 3) in vec3 a_PickingColor; +layout(location = ATTRIBUTE_LOCATION_PICKING_COLOR) in vec3 a_PickingColor; out vec4 v_PickingResult; #pragma include "picking_uniforms" diff --git a/packages/core/src/shaders/projection.glsl b/packages/core/src/shaders/projection.glsl index 5181d927356..673179bce4e 100644 --- a/packages/core/src/shaders/projection.glsl +++ b/packages/core/src/shaders/projection.glsl @@ -1,41 +1,32 @@ -#define TILE_SIZE 512.0 -#define PI 3.1415926536 -#define WORLD_SCALE TILE_SIZE / (PI * 2.0) -#define EARTH_CIRCUMFERENCE 40.03e6 +#define TILE_SIZE (512.0) +#define PI (3.1415926536) +#define WORLD_SCALE (TILE_SIZE / (PI * 2.0)) +#define EARTH_CIRCUMFERENCE (40.03e6) -#define COORDINATE_SYSTEM_LNGLAT 1.0 // mapbox -#define COORDINATE_SYSTEM_LNGLAT_OFFSET 2.0 // mapbox offset -#define COORDINATE_SYSTEM_VECTOR_TILE 3.0 -#define COORDINATE_SYSTEM_IDENTITY 4.0 -#define COORDINATE_SYSTEM_P20 5.0 // amap -#define COORDINATE_SYSTEM_P20_OFFSET 6.0 // amap offset -#define COORDINATE_SYSTEM_METER_OFFSET 7.0 +#define COORDINATE_SYSTEM_LNGLAT (1.0) // mapbox +#define COORDINATE_SYSTEM_LNGLAT_OFFSET (2.0) // mapbox offset +#define COORDINATE_SYSTEM_VECTOR_TILE (3.0) +#define COORDINATE_SYSTEM_IDENTITY (4.0) +#define COORDINATE_SYSTEM_METER_OFFSET (5.0) -#define COORDINATE_SYSTEM_P20_2 8.0 // amap2.0 #pragma include "scene_uniforms" +const vec2 ZERO_64_XY_LOW = vec2(0.0, 0.0); // web mercator coords -> world coords vec2 project_mercator(vec2 lnglat) { - if (u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.0 - return lnglat; - } float x = lnglat.x; - return vec2( - radians(x) + PI, - PI - log(tan(PI * 0.25 + radians(lnglat.y) * 0.5)) - ); + return vec2(radians(x) + PI, PI - log(tan(PI * 0.25 + radians(lnglat.y) * 0.5))); } float project_scale(float meters) { return meters * u_PixelsPerMeter.z; } - // offset coords -> world coords vec4 project_offset(vec4 offset) { float dy = offset.y; - dy = clamp(dy, -1., 1.); + dy = clamp(dy, -1.0, 1.0); vec3 pixels_per_unit = u_PixelsPerDegree + u_PixelsPerDegree2 * dy; return vec4(offset.xyz * pixels_per_unit, offset.w); } @@ -46,186 +37,106 @@ vec3 project_normal(vec3 normal) { } vec3 project_offset_normal(vec3 vector) { - if (u_CoordinateSystem < COORDINATE_SYSTEM_LNGLAT + 0.01 && u_CoordinateSystem >COORDINATE_SYSTEM_LNGLAT - 0.01 - || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { + if ( + u_CoordinateSystem < COORDINATE_SYSTEM_LNGLAT + 0.01 && + u_CoordinateSystem > COORDINATE_SYSTEM_LNGLAT - 0.01 || + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET + ) { // normals generated by the polygon tesselator are in lnglat offsets instead of meters return normalize(vector * u_PixelsPerDegree); } return project_normal(vector); } -// || u_CoordinateSystem < COORDINATE_SYSTEM_P20_OFFSET + 0.01 && u_CoordinateSystem >COORDINATE_SYSTEM_P20_OFFSET - 0.01 -// reverse Y -vec3 reverse_offset_normal(vec3 vector) { - if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 ||u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET ) { - return vector * vec3(1.0, -1.0, 1.0); - } - - if (u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.0 - return vector; - } - return vector; -} - -vec4 project_mvt_offset_position(vec4 position) { - float a = COORDINATE_SYSTEM_LNGLAT_OFFSET; - float b = COORDINATE_SYSTEM_P20_OFFSET; - float c = COORDINATE_SYSTEM_LNGLAT; - if (u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) { - return project_offset(vec4(0.0, 0.0, position.z, position.w)); - } - if (u_CoordinateSystem < COORDINATE_SYSTEM_LNGLAT + 0.01 && u_CoordinateSystem >COORDINATE_SYSTEM_LNGLAT - 0.01) { - return vec4( - project_mercator(position.xy) * WORLD_SCALE * u_ZoomScale, - project_scale(position.z), - position.w - ); - } - return position; -} -vec4 project_position(vec4 position) { - float a = COORDINATE_SYSTEM_LNGLAT_OFFSET; - float b = COORDINATE_SYSTEM_P20_OFFSET; - float c = COORDINATE_SYSTEM_LNGLAT; - if (u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET - || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) { +vec4 project_position(vec4 position, vec2 position64xyLow) { + if (u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { float X = position.x - u_ViewportCenter.x; float Y = position.y - u_ViewportCenter.y; - return project_offset(vec4(X, Y, position.z, position.w)); - } - if (u_CoordinateSystem < COORDINATE_SYSTEM_LNGLAT + 0.01 && u_CoordinateSystem >COORDINATE_SYSTEM_LNGLAT - 0.01) { - return vec4( - project_mercator(position.xy) * WORLD_SCALE * u_ZoomScale, - project_scale(position.z), - position.w + return project_offset( + vec4(X + position64xyLow.x, Y + position64xyLow.y, position.z, position.w) ); } - if (u_CoordinateSystem == COORDINATE_SYSTEM_P20) { + if ( + u_CoordinateSystem < COORDINATE_SYSTEM_LNGLAT + 0.01 && + u_CoordinateSystem > COORDINATE_SYSTEM_LNGLAT - 0.01 + ) { return vec4( - (project_mercator(position.xy) * WORLD_SCALE * u_ZoomScale - vec2(215440491., 106744817.)) * vec2(1., -1.), + project_mercator(position.xy) * WORLD_SCALE * u_ZoomScale, project_scale(position.z), position.w ); } - // if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { - - - // return vec4( - // position.xy, - // project_scale(position.z), - // position.w); - // } return position; +} - // TODO: 瓦片坐标系 & 常规世界坐标系 +vec4 project_position(vec4 position) { + return project_position(position, ZERO_64_XY_LOW); } + vec2 project_pixel_size_to_clipspace(vec2 pixels) { vec2 offset = pixels / u_ViewportSize * u_DevicePixelRatio * 2.0; return offset * u_FocalDistance; } - - -float project_pixel_allmap(float pixel) { - if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT) { - return pixel * pow(2.0, u_Zoom); - } - return pixel * u_FocalDistance ; -} - // 适配纹理贴图的等像素大小 float project_pixel_texture(float pixel) { // mapbox zoom > 12 - if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { - return pixel * pow(0.5, u_Zoom) * u_FocalDistance ; - } - - // amap2 zoom > 12 - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { - return pixel * pow(2.0, (19.0 - 3.0 - u_Zoom))* u_FocalDistance ; + if (u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { + return pixel * pow(0.5, u_Zoom) * u_FocalDistance; } - // amap zoom > 12 - if (u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) { - return pixel * pow(0.5, u_Zoom)* u_FocalDistance ; - } - - // amap zoom < 12 - if (u_CoordinateSystem == COORDINATE_SYSTEM_P20) { - return pixel * pow(2.0, (20.0 - u_Zoom))* u_FocalDistance ; - } - return pixel * 2.0 * u_FocalDistance;; + return pixel * 2.0 * u_FocalDistance; } // 在不论什么底图下需要统一处理的时候使用 float project_float_pixel(float pixel) { - if (u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { - // mapbox P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1 - return pixel * pow(2.0, (19.0 - u_Zoom)) * u_FocalDistance ; - } - if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) { - // amap P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1 - return pixel * pow(2.0, (19.0 - u_Zoom)); - } - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { - // amap2 P20_2 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减3 - return pixel * pow(2.0, (19.0 - 3.0 - u_Zoom))* u_FocalDistance ; + if ( + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET + ) { + // mapbox 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1 + return pixel * pow(2.0, 19.0 - u_Zoom) * u_FocalDistance; } + return pixel * u_FocalDistance; } // Project meter into the unit of pixel which used in the camera world space float project_float_meter(float meter) { - if (u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { + if ( + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET + ) { // Since the zoom level uniform is updated by mapservice and it's alread been subtracted by 1 // Not sure if we are supposed to do that again - return meter; - } else { + return meter; + } else { return project_float_pixel(meter); } // TODO: change the following code to make adaptations for amap // return u_FocalDistance * TILE_SIZE * pow(2.0, u_Zoom) * meter / EARTH_CIRCUMFERENCE; + } float project_pixel(float pixel) { - if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) { - // amap P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1 - return pixel * pow(2.0, (19.0 - u_Zoom)) * u_FocalDistance ; - } - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { - // amap2 P20_2 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减3 - return pixel * pow(2.0, (19.0 - 3.0 - u_Zoom)) * u_FocalDistance ; - } return pixel * u_FocalDistance; } + vec2 project_pixel(vec2 pixel) { - if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) { - // P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1 - return pixel * pow(2.0, (19.0 - u_Zoom)) * u_FocalDistance ; - } - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { - // P20_2 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减3 - return pixel * pow(2.0, (19.0 - 3.0 - u_Zoom)) * u_FocalDistance ; - } - return pixel * -1. * u_FocalDistance; + return pixel * -1.0 * u_FocalDistance; } + vec3 project_pixel(vec3 pixel) { - if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) { - // P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1 - return pixel * pow(2.0, (19.0 - u_Zoom)) * u_FocalDistance ; - } - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { - // P20_2 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减3 - return pixel * pow(2.0, (19.0 - 3.0 - u_Zoom)) * u_FocalDistance ; - } - return pixel * -1. * u_FocalDistance; + return pixel * -1.0 * u_FocalDistance; } vec4 project_common_position_to_clipspace(vec4 position, mat4 viewProjectionMatrix, vec4 center) { - if (u_CoordinateSystem == COORDINATE_SYSTEM_METER_OFFSET || - u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { + if ( + u_CoordinateSystem == COORDINATE_SYSTEM_METER_OFFSET || + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET + ) { // Needs to be divided with project_uCommonUnitsPerMeter position.w *= u_PixelsPerMeter.z; } @@ -245,24 +156,17 @@ vec4 project_common_position_to_clipspace(vec4 position) { vec4 unproject_clipspace_to_position(vec4 clipspacePos, mat4 u_InverseViewProjectionMatrix) { vec4 pos = u_InverseViewProjectionMatrix * (clipspacePos - u_ViewportCenterProjection); - if (u_CoordinateSystem == COORDINATE_SYSTEM_METER_OFFSET || - u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { + if ( + u_CoordinateSystem == COORDINATE_SYSTEM_METER_OFFSET || + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET + ) { // Needs to be divided with project_uCommonUnitsPerMeter - pos.w = pos.w / u_PixelsPerMeter.z; + pos.w = pos.w / u_PixelsPerMeter.z; } return pos; } - -bool isEqual( float a, float b) { - return a< b + 0.001 && a > b - 0.001; +bool isEqual(float a, float b) { + return a < b + 0.001 && a > b - 0.001; } -// 支持 GaodeV2、Mapbox -vec4 project_common_position_to_clipspace_v2(vec4 position) { - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x - return u_Mvp * position; - } else { - return project_common_position_to_clipspace(position); - } -} diff --git a/packages/core/src/shaders/scene_uniforms.glsl b/packages/core/src/shaders/scene_uniforms.glsl index 5bf5bfc96d8..efb25c006c8 100644 --- a/packages/core/src/shaders/scene_uniforms.glsl +++ b/packages/core/src/shaders/scene_uniforms.glsl @@ -16,8 +16,3 @@ layout(std140) uniform SceneUniforms { vec2 u_ViewportSize; float u_FocalDistance; }; - -layout(std140) uniform LayerUniforms { - mat4 u_Mvp; - vec2 u_sceneCenterMercator; -}; diff --git a/packages/l7/CHANGELOG.md b/packages/l7/CHANGELOG.md index dc53d0b7a5a..5013f9fa2f7 100644 --- a/packages/l7/CHANGELOG.md +++ b/packages/l7/CHANGELOG.md @@ -1,5 +1,109 @@ # Change Log +## 2.21.11-beta.7 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-scene@2.21.11-beta.7 + - @antv/l7-component@2.21.11-beta.7 + - @antv/l7-layers@2.21.11-beta.7 + - @antv/l7-core@2.21.11-beta.7 + - @antv/l7-maps@2.21.11-beta.7 + - @antv/l7-source@2.21.11-beta.7 + - @antv/l7-utils@2.21.11-beta.7 + +## 2.21.11-beta.6 + +### Patch Changes + +- Updated dependencies [[`67647e9`](https://github.com/antvis/L7/commit/67647e95c5b06b593604310c78c6a0ec195c3a01)]: + - @antv/l7-layers@2.21.11-beta.6 + - @antv/l7-component@2.21.11-beta.6 + - @antv/l7-scene@2.21.11-beta.6 + - @antv/l7-maps@2.21.11-beta.6 + - @antv/l7-core@2.21.11-beta.6 + - @antv/l7-source@2.21.11-beta.6 + - @antv/l7-utils@2.21.11-beta.6 + +## 2.21.11-beta.5 + +### Patch Changes + +- Updated dependencies [[`8939e9b`](https://github.com/antvis/L7/commit/8939e9bc0e744d75b5b469c221d6695c7a313e83)]: + - @antv/l7-maps@2.21.11-beta.5 + - @antv/l7-layers@2.21.11-beta.5 + - @antv/l7-scene@2.21.11-beta.5 + - @antv/l7-component@2.21.11-beta.5 + - @antv/l7-core@2.21.11-beta.5 + - @antv/l7-source@2.21.11-beta.5 + - @antv/l7-utils@2.21.11-beta.5 + +## 2.21.11-beta.4 + +### Patch Changes + +- Updated dependencies [[`cca16a3`](https://github.com/antvis/L7/commit/cca16a3d72de462afa9d71c386c82f92952d1c47)]: + - @antv/l7-maps@2.21.11-beta.4 + - @antv/l7-layers@2.21.11-beta.4 + - @antv/l7-scene@2.21.11-beta.4 + - @antv/l7-component@2.21.11-beta.4 + - @antv/l7-core@2.21.11-beta.4 + - @antv/l7-source@2.21.11-beta.4 + - @antv/l7-utils@2.21.11-beta.4 + +## 2.21.11-beta.3 + +### Patch Changes + +- Updated dependencies [[`aca779d`](https://github.com/antvis/L7/commit/aca779dac55ebf9ee1116106d69e71bb872b4ccc), [`a5f57ed`](https://github.com/antvis/L7/commit/a5f57eda52dab160fe076f252ad52cd51b8f456a)]: + - @antv/l7-component@2.21.11-beta.3 + - @antv/l7-core@2.21.11-beta.3 + - @antv/l7-scene@2.21.11-beta.3 + - @antv/l7-layers@2.21.11-beta.3 + - @antv/l7-maps@2.21.11-beta.3 + - @antv/l7-source@2.21.11-beta.3 + - @antv/l7-utils@2.21.11-beta.3 + +## 2.21.11-beta.2 + +### Patch Changes + +- Updated dependencies [[`0754eeb`](https://github.com/antvis/L7/commit/0754eebe5c029c808958a5f29492ed2487263c7f)]: + - @antv/l7-layers@2.21.11-beta.2 + - @antv/l7-component@2.21.11-beta.2 + - @antv/l7-scene@2.21.11-beta.2 + - @antv/l7-core@2.21.11-beta.2 + - @antv/l7-maps@2.21.11-beta.2 + - @antv/l7-source@2.21.11-beta.2 + - @antv/l7-utils@2.21.11-beta.2 + +## 2.21.11-beta.1 + +### Patch Changes + +- Updated dependencies [[`05dd5cc`](https://github.com/antvis/L7/commit/05dd5ccf31e12a9440efbebc9fcb803c594b5a44)]: + - @antv/l7-scene@2.21.11-beta.1 + - @antv/l7-component@2.21.11-beta.1 + - @antv/l7-layers@2.21.11-beta.1 + - @antv/l7-core@2.21.11-beta.1 + - @antv/l7-maps@2.21.11-beta.1 + - @antv/l7-source@2.21.11-beta.1 + - @antv/l7-utils@2.21.11-beta.1 + +## 2.21.11-beta.0 + +### Patch Changes + +- Updated dependencies [[`3e33888`](https://github.com/antvis/L7/commit/3e33888a56c6efa80be60bc79182644eaccaa500), [`05dd5cc`](https://github.com/antvis/L7/commit/05dd5ccf31e12a9440efbebc9fcb803c594b5a44), [`d408bdb`](https://github.com/antvis/L7/commit/d408bdb4a2a7be57a50f9a88247cf7b690ba4387)]: + - @antv/l7-layers@2.21.11-beta.0 + - @antv/l7-scene@2.21.11-beta.0 + - @antv/l7-component@2.21.11-beta.0 + - @antv/l7-core@2.21.11-beta.0 + - @antv/l7-maps@2.21.11-beta.0 + - @antv/l7-source@2.21.11-beta.0 + - @antv/l7-utils@2.21.11-beta.0 + ## 2.21.10 ### Patch Changes diff --git a/packages/l7/package.json b/packages/l7/package.json index 4d16feca54f..6d809966dcc 100644 --- a/packages/l7/package.json +++ b/packages/l7/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7", - "version": "2.21.10", + "version": "2.21.11-beta.7", "description": "A Large-scale WebGL-powered Geospatial Data Visualization", "repository": "git@github.com:antvis/L7.git", "license": "MIT", diff --git a/packages/layers/CHANGELOG.md b/packages/layers/CHANGELOG.md index d99f7d2789c..f1ffe55d920 100644 --- a/packages/layers/CHANGELOG.md +++ b/packages/layers/CHANGELOG.md @@ -1,5 +1,93 @@ # Change Log +## 2.21.11-beta.7 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.7 + - @antv/l7-maps@2.21.11-beta.7 + - @antv/l7-source@2.21.11-beta.7 + - @antv/l7-utils@2.21.11-beta.7 + +## 2.21.11-beta.6 + +### Patch Changes + +- [#2523](https://github.com/antvis/L7/pull/2523) [`67647e9`](https://github.com/antvis/L7/commit/67647e95c5b06b593604310c78c6a0ec195c3a01) Thanks [@lvisei](https://github.com/lvisei)! - fix: 解决 GeometryLayer 在不同底图上的渲染不一致情况 + +- Updated dependencies []: + - @antv/l7-maps@2.21.11-beta.6 + - @antv/l7-core@2.21.11-beta.6 + - @antv/l7-source@2.21.11-beta.6 + - @antv/l7-utils@2.21.11-beta.6 + +## 2.21.11-beta.5 + +### Patch Changes + +- Updated dependencies [[`8939e9b`](https://github.com/antvis/L7/commit/8939e9bc0e744d75b5b469c221d6695c7a313e83)]: + - @antv/l7-maps@2.21.11-beta.5 + - @antv/l7-core@2.21.11-beta.5 + - @antv/l7-source@2.21.11-beta.5 + - @antv/l7-utils@2.21.11-beta.5 + +## 2.21.11-beta.4 + +### Patch Changes + +- Updated dependencies [[`cca16a3`](https://github.com/antvis/L7/commit/cca16a3d72de462afa9d71c386c82f92952d1c47)]: + - @antv/l7-maps@2.21.11-beta.4 + - @antv/l7-core@2.21.11-beta.4 + - @antv/l7-source@2.21.11-beta.4 + - @antv/l7-utils@2.21.11-beta.4 + +## 2.21.11-beta.3 + +### Patch Changes + +- Updated dependencies [[`a5f57ed`](https://github.com/antvis/L7/commit/a5f57eda52dab160fe076f252ad52cd51b8f456a)]: + - @antv/l7-core@2.21.11-beta.3 + - @antv/l7-maps@2.21.11-beta.3 + - @antv/l7-source@2.21.11-beta.3 + - @antv/l7-utils@2.21.11-beta.3 + +## 2.21.11-beta.2 + +### Patch Changes + +- [#2500](https://github.com/antvis/L7/pull/2500) [`0754eeb`](https://github.com/antvis/L7/commit/0754eebe5c029c808958a5f29492ed2487263c7f) Thanks [@lvisei](https://github.com/lvisei)! - fix: 修复热力蜂窝图层渲染空白 + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.2 + - @antv/l7-maps@2.21.11-beta.2 + - @antv/l7-source@2.21.11-beta.2 + - @antv/l7-utils@2.21.11-beta.2 + +## 2.21.11-beta.1 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.1 + - @antv/l7-maps@2.21.11-beta.1 + - @antv/l7-source@2.21.11-beta.1 + - @antv/l7-utils@2.21.11-beta.1 + +## 2.21.11-beta.0 + +### Patch Changes + +- [#2474](https://github.com/antvis/L7/pull/2474) [`3e33888`](https://github.com/antvis/L7/commit/3e33888a56c6efa80be60bc79182644eaccaa500) Thanks [@lvisei](https://github.com/lvisei)! - fix: mapbox 线图层的贴图变形 + +- [#2453](https://github.com/antvis/L7/pull/2453) [`d408bdb`](https://github.com/antvis/L7/commit/d408bdb4a2a7be57a50f9a88247cf7b690ba4387) Thanks [@lvisei](https://github.com/lvisei)! - fix: mapbox 下部分面数据图层绘制异常 + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.0 + - @antv/l7-maps@2.21.11-beta.0 + - @antv/l7-source@2.21.11-beta.0 + - @antv/l7-utils@2.21.11-beta.0 + ## 2.21.10 ### Patch Changes diff --git a/packages/layers/__tests__/raster/raster.spec.ts b/packages/layers/__tests__/raster/raster.spec.ts index 9c214ba8732..5cb2b1a37eb 100644 --- a/packages/layers/__tests__/raster/raster.spec.ts +++ b/packages/layers/__tests__/raster/raster.spec.ts @@ -1,7 +1,7 @@ +import { TestScene } from '@antv/l7-test-utils'; import RasterLayer from '../../src/raster/index'; import { raster_data } from './data'; -import { TestScene } from '@antv/l7-test-utils'; describe('RasterLayer', () => { let scene: any; beforeEach(() => { diff --git a/packages/layers/__tests__/wind/wind.spec.ts b/packages/layers/__tests__/wind/wind.spec.ts index 27bcde03676..5b2036599e2 100644 --- a/packages/layers/__tests__/wind/wind.spec.ts +++ b/packages/layers/__tests__/wind/wind.spec.ts @@ -38,6 +38,8 @@ describe('WindLayer', () => { 1.0: '#d53e4f', }, }); - scene.addLayer(layer); + + // TODO: LLVM ERROR: out of memory + // scene.addLayer(layer); }); }); diff --git a/packages/layers/package.json b/packages/layers/package.json index e31fea8dedf..8cdfd46152c 100644 --- a/packages/layers/package.json +++ b/packages/layers/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7-layers", - "version": "2.21.10", + "version": "2.21.11-beta.7", "description": "L7's collection of built-in layers", "license": "MIT", "author": "https://github.com/orgs/antvis/people", diff --git a/packages/layers/src/citybuliding/models/build.ts b/packages/layers/src/citybuliding/models/build.ts index 3f55013a333..71d2cdd4c1e 100644 --- a/packages/layers/src/citybuliding/models/build.ts +++ b/packages/layers/src/citybuliding/models/build.ts @@ -2,12 +2,21 @@ import type { IEncodeFeature, IModel } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; import { rgb2arr } from '@antv/l7-utils'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import type { ICityBuildLayerStyleOptions } from '../../core/interface'; import { PolygonExtrudeTriangulation } from '../../core/triangulation'; import buildFrag from '../shaders/build_frag.glsl'; import buildVert from '../shaders/build_vert.glsl'; + export default class CityBuildModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + SIZE: 9, + NORMAL: 10, + UV: 11, + }); + } + private cityCenter: [number, number]; private cityMinSize: number; protected getCommonUniformsInfo(): { @@ -51,23 +60,11 @@ export default class CityBuildModel extends BaseModel { public calCityGeo() { // @ts-ignore const [minLng, minLat, maxLng, maxLat] = this.layer.getSource().extent; - if (this.mapService.version === 'GAODE2.x') { - // @ts-ignore - this.cityCenter = this.mapService.lngLatToCoord([ - (maxLng + minLng) / 2, - (maxLat + minLat) / 2, - ]); - // @ts-ignore - const l1 = this.mapService.lngLatToCoord([maxLng, maxLat]); - // @ts-ignore - const l2 = this.mapService.lngLatToCoord([minLng, minLat]); - this.cityMinSize = Math.sqrt(Math.pow(l1[0] - l2[0], 2) + Math.pow(l1[1] - l2[1], 2)) / 4; - } else { - const w = maxLng - minLng; - const h = maxLat - minLat; - this.cityCenter = [(maxLng + minLng) / 2, (maxLat + minLat) / 2]; - this.cityMinSize = Math.sqrt(Math.pow(w, 2) + Math.pow(h, 2)) / 4; - } + + const w = maxLng - minLng; + const h = maxLat - minLat; + this.cityCenter = [(maxLng + minLng) / 2, (maxLat + minLat) / 2]; + this.cityMinSize = Math.sqrt(Math.pow(w, 2) + Math.pow(h, 2)) / 4; } public async initModels(): Promise { @@ -85,6 +82,7 @@ export default class CityBuildModel extends BaseModel { fragmentShader: buildFrag, triangulation: PolygonExtrudeTriangulation, depth: { enable: true }, + defines: this.getDefines(), inject: this.getInject(), cull: { enable: true, @@ -101,7 +99,7 @@ export default class CityBuildModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Normal', - shaderLocation: ShaderLocation.NORMAL, + shaderLocation: this.attributeLocation.NORMAL, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.STATIC_DRAW, @@ -126,7 +124,7 @@ export default class CityBuildModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Size', - shaderLocation: ShaderLocation.SIZE, + shaderLocation: this.attributeLocation.SIZE, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, @@ -145,7 +143,7 @@ export default class CityBuildModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Uv', - shaderLocation: ShaderLocation.UV, + shaderLocation: this.attributeLocation.UV, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, diff --git a/packages/layers/src/citybuliding/shaders/build_frag.glsl b/packages/layers/src/citybuliding/shaders/build_frag.glsl index 669b88e9ebb..aa135fd1926 100644 --- a/packages/layers/src/citybuliding/shaders/build_frag.glsl +++ b/packages/layers/src/citybuliding/shaders/build_frag.glsl @@ -1,16 +1,16 @@ precision highp float; layout(std140) uniform commonUniforms { - vec4 u_baseColor : [ 1.0, 0, 0, 1.0 ]; - vec4 u_brightColor : [ 1.0, 0, 0, 1.0 ]; - vec4 u_windowColor : [ 1.0, 0, 0, 1.0 ]; + vec4 u_baseColor: [ 1.0, 0, 0, 1.0 ]; + vec4 u_brightColor: [ 1.0, 0, 0, 1.0 ]; + vec4 u_windowColor: [ 1.0, 0, 0, 1.0 ]; vec4 u_circleSweepColor; vec2 u_cityCenter; float u_circleSweep; float u_cityMinSize; float u_circleSweepSpeed; float u_opacity: 1.0; - float u_near : 0; - float u_far : 1; + float u_near: 0; + float u_far: 1; float u_time; }; in vec4 v_Color; @@ -114,7 +114,7 @@ void main() { float r = fract(((v_worldDis/u_cityMinSize) - u_time * u_circleSweepSpeed) * 2.0); outputColor.rgb += r * r * u_circleSweepColor.rgb; } - + outputColor.a *= u_opacity; outputColor = filterColor(outputColor); } diff --git a/packages/layers/src/citybuliding/shaders/build_vert.glsl b/packages/layers/src/citybuliding/shaders/build_vert.glsl index 54118f530e9..4de32b7a53a 100644 --- a/packages/layers/src/citybuliding/shaders/build_vert.glsl +++ b/packages/layers/src/citybuliding/shaders/build_vert.glsl @@ -4,11 +4,11 @@ precision highp float; #define diffuseRatio 0.3 #define specularRatio 0.2 -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in float a_Size; -layout(location = 13) in vec3 a_Normal; -layout(location = 14) in vec2 a_Uv; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in float a_Size; +layout(location = ATTRIBUTE_LOCATION_NORMAL) in vec3 a_Normal; +layout(location = ATTRIBUTE_LOCATION_UV) in vec2 a_Uv; out vec2 v_texCoord; out vec4 v_Color; @@ -41,17 +41,11 @@ void main() { if(u_circleSweep > 0.0) { vec2 lnglatscale = vec2(0.0); - if(u_CoordinateSystem != COORDINATE_SYSTEM_P20_2) { - lnglatscale = (a_Position.xy - u_cityCenter) * vec2(0.0, 0.135); - } + lnglatscale = (a_Position.xy - u_cityCenter) * vec2(0.0, 0.135); v_worldDis = length(a_Position.xy + lnglatscale - u_cityCenter); } - - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x - gl_Position = u_Mvp * (vec4(project_pos.xyz, 1.0)); - } else { - gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); - } + + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); float lightWeight = calc_lighting(pos); // v_Color = a_Color; diff --git a/packages/layers/src/core/BaseLayer.ts b/packages/layers/src/core/BaseLayer.ts index 3b3a1a3d894..be8e331fbbf 100644 --- a/packages/layers/src/core/BaseLayer.ts +++ b/packages/layers/src/core/BaseLayer.ts @@ -184,7 +184,7 @@ export default class BaseLayer } protected get mapService() { - return this.container.mapService; + return this.container?.mapService; } public styleAttributeService: IStyleAttributeService; @@ -1065,9 +1065,6 @@ export default class BaseLayer if (this.coordCenter === undefined) { const layerCenter = this.layerSource.center; this.coordCenter = layerCenter; - if (this.mapService?.setCoordCenter) { - this.mapService.setCoordCenter(layerCenter); - } } if (type === 'update') { if (this.tileLayer) { @@ -1171,6 +1168,7 @@ export default class BaseLayer moduleName, vertexShader, fragmentShader, + defines, inject, triangulation, styleOption, @@ -1180,6 +1178,7 @@ export default class BaseLayer this.shaderModuleService.registerModule(moduleName, { vs: vertexShader, fs: fragmentShader, + defines, inject, }); const { vs, fs, uniforms } = this.shaderModuleService.getModule(moduleName); @@ -1195,7 +1194,6 @@ export default class BaseLayer const uniformBuffers = [ ...this.layerModel.uniformBuffers, ...this.rendererService.uniformBuffers, - this.getLayerUniformBuffer(), ]; if (pickingEnabled) { uniformBuffers.push(this.getPickingUniformBuffer()); @@ -1412,28 +1410,20 @@ export default class BaseLayer buffer.destroy(); }); this.uniformBuffers = []; - // Layer Uniform - const layerUniforms = this.rendererService.createBuffer({ - data: new Float32Array(16 + 4).fill(0), // u_Mvp - isUBO: true, - }); - this.uniformBuffers.push(layerUniforms); // Picking Uniform const pickingUniforms = this.rendererService.createBuffer({ data: new Float32Array(20).fill(0), isUBO: true, + label: 'pickingUniforms', }); this.uniformBuffers.push(pickingUniforms); this.models = await this.layerModel.initModels(); } - getLayerUniformBuffer() { - return this.uniformBuffers[0]; - } getPickingUniformBuffer() { - return this.uniformBuffers[1]; + return this.uniformBuffers[0]; } protected reRender() { diff --git a/packages/layers/src/core/BaseModel.ts b/packages/layers/src/core/BaseModel.ts index a9ec7c5efef..a416b977773 100644 --- a/packages/layers/src/core/BaseModel.ts +++ b/packages/layers/src/core/BaseModel.ts @@ -5,10 +5,10 @@ import type { IBuffer, ICameraService, IElements, + IEncodeFeature, IFontService, IGlobalConfigService, IIconService, - IInject, ILayer, ILayerConfig, ILayerModel, @@ -17,20 +17,22 @@ import type { IModel, IModelUniform, IPickingService, - IRendererService, IRenderOptions, + IRendererService, IShaderModuleService, IStencilOptions, IStyleAttributeService, ITexture2D, ITexture2DInitializationOptions, + ShaderDefine, + ShaderInject, Triangulation, } from '@antv/l7-core'; -import { BlendType, MaskOperation, StencilType } from '@antv/l7-core'; -import { rgb2arr } from '@antv/l7-utils'; +import { AttributeType, BlendType, MaskOperation, StencilType, gl } from '@antv/l7-core'; +import { fp64LowPart, rgb2arr } from '@antv/l7-utils'; import { BlendTypes } from '../utils/blend'; import { getStencil, getStencilMask } from '../utils/stencil'; -import { getCommonStyleAttributeOptions, ShaderLocation } from './CommonStyleAttribute'; +import { COMMON_ATTRIBUTE_LOCATION, getCommonStyleAttributeOptions } from './CommonStyleAttribute'; import { DefaultUniformStyleType, DefaultUniformStyleValue } from './constant'; import { MultipleOfFourNumber } from './utils'; export type styleSingle = @@ -51,20 +53,22 @@ export interface ICellProperty { count: number; } -const shaderLocationMap: Record = { - opacity: ShaderLocation.OPACITY, - stroke: ShaderLocation.STROKE, - offsets: ShaderLocation.OFFSETS, - rotation: ShaderLocation.ROTATION, - extrusionBase: ShaderLocation.EXTRUSION_BASE, - thetaOffset: 15, -}; +type AttributeLayoutLocationType = typeof COMMON_ATTRIBUTE_LOCATION & Record; + +// 属性索引宏定义前缀,使用命名空间避免 define 名称重复情况 +const DEFINE_ATTRIBUTE_LOCATION_PREFIX = 'ATTRIBUTE_LOCATION_'; // eslint-disable-next-line @typescript-eslint/no-unused-vars export default class BaseModel implements ILayerModel { public triangulation: Triangulation; public uniformBuffers: IBuffer[] = []; public textures: ITexture2D[] = []; + /** + * Attribute Layout Location in Shader + */ + protected get attributeLocation(): AttributeLayoutLocationType { + return { ...COMMON_ATTRIBUTE_LOCATION }; + } // style texture data mapping public createTexture2D: (options: ITexture2DInitializationOptions) => ITexture2D; @@ -229,60 +233,26 @@ export default class BaseModel implements ILayerMod } } - // 动态注入参与数据映射的uniform - protected getInject(): IInject { - const encodeStyleAttribute = this.layer.encodeStyleAttribute; - let str = ''; - // a_Position = 0 - // a_Color = 1 - // a_PickingColor = 2 - - const uniforms: string[] = []; - // 支持数据映射的类型 - this.layer.enableShaderEncodeStyles.forEach((key: string) => { - if (encodeStyleAttribute[key]) { - // 配置了数据映射的类型 - str += `#define USE_ATTRIBUTE_${key.toUpperCase()} 0.0; \n\n`; - } else { - uniforms.push(` ${DefaultUniformStyleType[key]} u_${key};`); - } - let location = shaderLocationMap[key]; - if (!location && key === 'THETA_OFFSET') { - location = 15; - } - str += ` - #ifdef USE_ATTRIBUTE_${key.toUpperCase()} - layout(location = ${shaderLocationMap[key]}) in ${ - DefaultUniformStyleType[key] - } a_${key.charAt(0).toUpperCase() + key.slice(1)}; - #endif\n - `; - }); - const attributeUniforms = uniforms.length - ? ` -layout(std140) uniform AttributeUniforms { -${uniforms.join('\n')} -}; - ` - : ''; - str += attributeUniforms; + protected getInject(): ShaderInject { + const shaderInject = getDynamicStyleInject( + this.layer.enableShaderEncodeStyles, + this.layer.encodeStyleAttribute, + ); - let innerStr = ''; - this.layer.enableShaderEncodeStyles.forEach((key) => { - innerStr += `\n - #ifdef USE_ATTRIBUTE_${key.toUpperCase()} - ${DefaultUniformStyleType[key]} ${key} = a_${key.charAt(0).toUpperCase() + key.slice(1)}; - #else - ${DefaultUniformStyleType[key]} ${key} = u_${key}; - #endif\n - `; - }); + return shaderInject; + } - return { - 'vs:#decl': str, - 'fs:#decl': attributeUniforms, - 'vs:#main-start': innerStr, - }; + protected getDefines(): Record { + // define atribute Layout Location + const atributeLocationDefines = Object.keys(this.attributeLocation).reduce< + Record + >((result, key) => { + const normalizedKey = DEFINE_ATTRIBUTE_LOCATION_PREFIX + key; + result[normalizedKey] = this.attributeLocation[key]; + return result; + }, {}); + + return { ...atributeLocationDefines }; } // 获取数据映射样式 @@ -304,19 +274,41 @@ ${uniforms.join('\n')} }); return options; } + // 注册数据映射样式 protected registerStyleAttribute() { Object.keys(this.layer.encodeStyleAttribute).forEach((key) => { const options = getCommonStyleAttributeOptions(key); if (options) { this.styleAttributeService.registerStyleAttribute(options); - - if (options.descriptor) { - options.descriptor.shaderLocation = shaderLocationMap[key]; - } } }); } + + /** + * 注册 Position 属性 64 位地位部分,当经纬度数据开启双精度浮点数使用, + * 避免大于 20层级以上出现数据偏移 + */ + protected registerPosition64LowAttribute(enable64bitPosition = true) { + // save low part for enabled double precision POSITION attribute + this.styleAttributeService.registerStyleAttribute({ + name: 'position64Low', + type: AttributeType.Attribute, + descriptor: { + name: 'a_Position64Low', + shaderLocation: this.attributeLocation.POSITION_64LOW, + buffer: { + data: [], + type: gl.FLOAT, + }, + size: 2, + update: (feature: IEncodeFeature, featureIdx: number, vertex: number[]) => { + return enable64bitPosition ? [fp64LowPart(vertex[0]), fp64LowPart(vertex[1])] : [0, 0]; + }, + }, + }); + } + public updateEncodeAttribute(type: string, flag: boolean) { this.encodeStyleAttribute[type] = flag; } @@ -328,6 +320,7 @@ ${uniforms.join('\n')} this.attributeUnifoms = this.rendererService.createBuffer({ data: new Float32Array(MultipleOfFourNumber(attrUniforms.uniformsLength)).fill(0), // 长度需要大于等于 4 isUBO: true, + label: 'layerModelAttributeUnifoms', }); this.uniformBuffers.push(this.attributeUnifoms); } @@ -335,6 +328,7 @@ ${uniforms.join('\n')} this.commonUnifoms = this.rendererService.createBuffer({ data: new Float32Array(MultipleOfFourNumber(commonUniforms.uniformsLength)).fill(0), isUBO: true, + label: 'layerModelCommonUnifoms', }); this.uniformBuffers.push(this.commonUnifoms); } @@ -389,3 +383,59 @@ ${uniforms.join('\n')} }); } } + +/** + * 获取动态注入参与数据映射 uniform/attribute + */ +function getDynamicStyleInject( + shaderEncodeStyles: string[], + styleAttribute: Record, +): ShaderInject { + const uniforms: string[] = []; + let vsDeclInjection = ''; + + // 支持数据映射的类型 + shaderEncodeStyles.forEach((key) => { + const upperCaseKey = key.replace(/([a-z])([A-Z])/g, '$1_$2').toUpperCase(); + const shaderDefineName = DEFINE_ATTRIBUTE_LOCATION_PREFIX + upperCaseKey; + + if (styleAttribute[key]) { + // 配置了数据映射的类型 + vsDeclInjection += `#define USE_ATTRIBUTE_${upperCaseKey} 0.0 \n`; + } else { + uniforms.push(` ${DefaultUniformStyleType[key]} u_${key};`); + } + + vsDeclInjection += ` +#ifdef USE_ATTRIBUTE_${upperCaseKey} +layout(location = ${shaderDefineName}) in ${DefaultUniformStyleType[key]} a_${key.charAt(0).toUpperCase() + key.slice(1)}; +#endif \n`; + }); + + const fsDeclInjection = uniforms.length + ? ` +layout(std140) uniform AttributeUniforms { + ${uniforms.join('\n')} +};\n` + : ''; + + vsDeclInjection += fsDeclInjection; + + let vsMainInjection = ''; + shaderEncodeStyles.forEach((key) => { + const upperCaseKey = key.replace(/([a-z])([A-Z])/g, '$1_$2').toUpperCase(); + vsMainInjection += ` + #ifdef USE_ATTRIBUTE_${upperCaseKey} + ${DefaultUniformStyleType[key]} ${key} = a_${key.charAt(0).toUpperCase() + key.slice(1)}; + #else + ${DefaultUniformStyleType[key]} ${key} = u_${key}; + #endif + `; + }); + + return { + 'vs:#decl': vsDeclInjection, + 'fs:#decl': fsDeclInjection, + 'vs:#main-start': vsMainInjection, + }; +} diff --git a/packages/layers/src/core/CommonStyleAttribute.ts b/packages/layers/src/core/CommonStyleAttribute.ts index c45fdba95ab..0e49ea74fcf 100644 --- a/packages/layers/src/core/CommonStyleAttribute.ts +++ b/packages/layers/src/core/CommonStyleAttribute.ts @@ -1,24 +1,26 @@ import type { IEncodeFeature, IStyleAttribute } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; -export enum ShaderLocation { - POSITION = 0, - COLOR, - VERTEX_ID, - PICKING_COLOR, - STROKE, - OPACITY, - OFFSETS, - ROTATION, - EXTRUSION_BASE, - SIZE, - SHAPE, - EXTRUDE, - MAX, - NORMAL, - UV, - LINEAR, // Polygon Linear -} +/** + * Attribute Layout Location in Shader + */ +export const COMMON_ATTRIBUTE_LOCATION = { + // common attribute in RegisterStyleAttributePlugin + POSITION: 0, + // low part for double precision POSITION attribute + POSITION_64LOW: 1, + COLOR: 2, + PICKING_COLOR: 3, + + // common style attribute + STROKE: 4, + OPACITY: 5, + OFFSETS: 6, + ROTATION: 7, + + // last index + MAX: 8, +} as const; export function getCommonStyleAttributeOptions(name: string): Partial | undefined { switch (name) { @@ -29,7 +31,7 @@ export function getCommonStyleAttributeOptions(name: string): Partial { - const { extrusionBase: op = 0 } = feature; - return [op]; - }, - }, - }; case 'offsets': return { name: 'offsets', type: AttributeType.Attribute, descriptor: { name: 'a_Offsets', - shaderLocation: ShaderLocation.OFFSETS, + shaderLocation: COMMON_ATTRIBUTE_LOCATION.OFFSETS, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.STATIC_DRAW, @@ -122,26 +104,6 @@ export function getCommonStyleAttributeOptions(name: string): Partial { - const { thetaOffset: op = 1 } = feature; - return [op]; - }, - }, - }; default: return undefined; } diff --git a/packages/layers/src/core/shape/extrude.ts b/packages/layers/src/core/shape/extrude.ts index d5edd94a07a..bd15dad95c8 100644 --- a/packages/layers/src/core/shape/extrude.ts +++ b/packages/layers/src/core/shape/extrude.ts @@ -1,7 +1,9 @@ import { lngLatToMeters } from '@antv/l7-utils'; import earcut from 'earcut'; import { vec3 } from 'gl-matrix'; +import { getPolygonSurfaceIndices } from '../utils'; import type { IPath } from './Path'; + export interface IExtrudeGeomety { positions: number[]; index: number[]; @@ -62,6 +64,7 @@ export default function extrudePolygon(path: IPath[]): IExtrudeGeomety { index: indexArray, }; } + export function fillPolygon(points: IPath[]) { const flattengeo = earcut.flatten(points); const triangles = earcut(flattengeo.vertices, flattengeo.holes, flattengeo.dimensions); @@ -82,7 +85,7 @@ export function extrude_PolygonNormal( } const n = path[0].length; const flattengeo = earcut.flatten(path); - const { vertices, dimensions } = flattengeo; + const { vertices, dimensions, holes } = flattengeo; const positions = []; const indexArray = []; const normals = []; @@ -97,8 +100,10 @@ export function extrude_PolygonNormal( ); normals.push(0, 0, 1); } - const triangles = earcut(flattengeo.vertices, flattengeo.holes, flattengeo.dimensions); - indexArray.push(...triangles); + + const indices = getPolygonSurfaceIndices(vertices, holes, dimensions, needFlat); + indexArray.push(...indices); + // 设置侧面 for (let i = 0; i < n; i++) { const prePoint = flattengeo.vertices.slice(i * dimensions, (i + 1) * dimensions); @@ -145,6 +150,7 @@ export function extrude_PolygonNormal( normals, }; } + function computeVertexNormals( p1: [number, number, number], p2: [number, number, number], diff --git a/packages/layers/src/core/triangulation.ts b/packages/layers/src/core/triangulation.ts index be752250b0f..3204f88f193 100644 --- a/packages/layers/src/core/triangulation.ts +++ b/packages/layers/src/core/triangulation.ts @@ -17,10 +17,11 @@ import { } from '../earth/utils'; import ExtrudePolyline from '../utils/extrude_polyline'; import type { IPosition, ShapeType2D, ShapeType3D } from './shape/Path'; +import { geometryShape } from './shape/Path'; import type { IExtrudeGeomety } from './shape/extrude'; import extrudePolygon, { extrude_PolygonNormal, fillPolygon } from './shape/extrude'; +import { getPolygonSurfaceIndices } from './utils'; -import { geometryShape } from './shape/Path'; type IShape = ShapeType2D & ShapeType3D; interface IGeometryCache { [key: string]: IExtrudeGeomety; @@ -87,7 +88,7 @@ export function PointImageTriangulation(feature: IEncodeFeature) { * @param feature 映射feature */ export function LineTriangulation(feature: IEncodeFeature) { - const { coordinates, originCoordinates, version } = feature; + const { coordinates } = feature; // let path = coordinates as number[][][] | number[][]; // if (!Array.isArray(path[0][0])) { // path = [coordinates] as number[][][]; @@ -98,33 +99,13 @@ export function LineTriangulation(feature: IEncodeFeature) { join: 'bevel', }); - if (version === 'GAODE2.x') { - // 处理高德2.0几何体构建 - let path1 = coordinates as number[][][] | number[][]; // 计算位置 - if (!Array.isArray(path1[0][0])) { - path1 = [coordinates] as number[][][]; - } - let path2 = originCoordinates as number[][][] | number[][]; // 计算法线 - if (!Array.isArray(path2[0][0])) { - path2 = [originCoordinates] as number[][][]; - } - - for (let i = 0; i < path1.length; i++) { - // 高德2.0在计算线时,需要使用经纬度计算发现,使用 customCoords.lnglatToCoords 计算的数据来计算顶点的位置 - const item1 = path1[i]; - const item2 = path2[i]; - line.extrude_gaode2(item1 as number[][], item2 as number[][]); - } - } else { - // 处理非高德2.0的几何体构建 - let path = coordinates as number[][][] | number[][]; - if (path[0] && !Array.isArray(path[0][0])) { - path = [coordinates] as number[][][]; - } - path.forEach((item: any) => { - line.extrude(item as number[][]); - }); + let path = coordinates as number[][][] | number[][]; + if (path[0] && !Array.isArray(path[0][0])) { + path = [coordinates] as number[][][]; } + path.forEach((item: any) => { + line.extrude(item as number[][]); + }); const linebuffer = line.complex; return { @@ -223,7 +204,7 @@ export function FlowLineFillTriangulation(feature: IEncodeFeature) { } export function SimpleLineTriangulation(feature: IEncodeFeature) { - const { coordinates, originCoordinates } = feature; + const { coordinates } = feature; const pos: any[] = []; if (!Array.isArray(coordinates[0])) { return { @@ -234,10 +215,7 @@ export function SimpleLineTriangulation(feature: IEncodeFeature) { count: 0, }; } - const { results, totalDistance } = getSimpleLineVertices( - coordinates as IPosition[], - originCoordinates as IPosition[], - ); + const { results, totalDistance } = getSimpleLineVertices(coordinates as IPosition[]); results.map((point) => { pos.push(point[0], point[1], point[2], point[3], 0, totalDistance); }); @@ -291,15 +269,11 @@ function pushDis(point: number[], n?: number) { return point; } -function getSimpleLineVertices(coordinates: number[][], originCoordinates: number[][]) { +function getSimpleLineVertices(coordinates: number[][]) { let points = coordinates; - //除了amap2.0以外 coordinates就是经纬度数据 - let originPoints = originCoordinates || coordinates; if (Array.isArray(points) && Array.isArray(points[0]) && Array.isArray(points[0][0])) { // @ts-ignore - points = originCoordinates.flat(); - // @ts-ignore - originPoints = originCoordinates.flat(); + points = coordinates.flat(); } //修改计算距离的方式,与普通线的计算方式保持一致 edit by huyang 20231214 let distance = 0; @@ -314,10 +288,7 @@ function getSimpleLineVertices(coordinates: number[][], originCoordinates: numbe results.push(point); for (let i = 1; i < points.length - 1; i++) { - const subDistance = lineSegmentDistance( - aProjectFlat(originPoints[i - 1]), - aProjectFlat(originPoints[i]), - ); + const subDistance = lineSegmentDistance(aProjectFlat(points[i - 1]), aProjectFlat(points[i])); distance += subDistance; const mulPoint = pushDis(points[i], distance); @@ -325,8 +296,8 @@ function getSimpleLineVertices(coordinates: number[][], originCoordinates: numbe results.push(mulPoint); } const pointDistance = lineSegmentDistance( - aProjectFlat(originPoints[originPoints.length - 2]), - aProjectFlat(originPoints[originPoints.length - 1]), + aProjectFlat(points[points.length - 2]), + aProjectFlat(points[points.length - 1]), ); distance += pointDistance; @@ -364,8 +335,11 @@ export function polygonTriangulation(feature: IEncodeFeature) { const { coordinates } = feature; const flattengeo = earcut.flatten(coordinates as number[][][]); const { vertices, dimensions, holes } = flattengeo; + + const indices = getPolygonSurfaceIndices(vertices, holes, dimensions); + return { - indices: earcut(vertices, holes, dimensions), + indices, vertices, size: dimensions, }; @@ -373,14 +347,12 @@ export function polygonTriangulation(feature: IEncodeFeature) { // 构建几何图形(带有中心点和大小) export function polygonTriangulationWithCenter(feature: IEncodeFeature) { - const { coordinates } = feature; - const flattengeo = earcut.flatten(coordinates as number[][][]); - const { vertices, dimensions, holes } = flattengeo; + const { indices, vertices, size } = polygonTriangulation(feature); return { - indices: earcut(vertices, holes, dimensions), + indices: indices, vertices: getVerticesWithCenter(vertices), - size: dimensions + 4, + size: size + 4, }; } diff --git a/packages/layers/src/core/utils.ts b/packages/layers/src/core/utils.ts index 3c9e8edf8ce..099e03e2a79 100644 --- a/packages/layers/src/core/utils.ts +++ b/packages/layers/src/core/utils.ts @@ -1,3 +1,45 @@ +import { lngLatToMeters } from '@antv/l7-utils'; +import earcut from 'earcut'; + export function MultipleOfFourNumber(num: number) { return Math.max(Math.ceil(num / 4) * 4, 4); } + +/** + * Get vertex indices for drawing polygon mesh (triangulation) + */ +export function getPolygonSurfaceIndices( + positions: number[], + holeIndices: number[], + positionSize: number, + preproject = true, +) { + const is3d = positionSize === 3; + + if (preproject) { + positions = positions.slice(); + const p: number[] = []; + for (let i = 0; i < positions.length; i += positionSize) { + p[0] = positions[i]; + p[1] = positions[i + 1]; + + if (is3d) { + p[2] = positions[i + 2]; + } + + // earcut is a 2D triangulation algorithm, and handles 3D data as if it was projected onto the XY plane + const xy = lngLatToMeters(p, true, { enable: false, decimal: 1 }); + + positions[i] = xy[0]; + positions[i + 1] = xy[1]; + + if (is3d) { + positions[i + 2] = xy[2]; + } + } + } + + const indices = earcut(positions, holeIndices, positionSize); + + return indices; +} diff --git a/packages/layers/src/earth/models/atmosphere.ts b/packages/layers/src/earth/models/atmosphere.ts index bca23db6e0d..038343287d9 100644 --- a/packages/layers/src/earth/models/atmosphere.ts +++ b/packages/layers/src/earth/models/atmosphere.ts @@ -2,16 +2,24 @@ import type { IEncodeFeature, IModel } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; import { lodashUtil } from '@antv/l7-utils'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import { earthTriangulation } from '../../core/triangulation'; import atmoSphereFrag from '../shaders/atmosphere/atmosphere_frag.glsl'; import atmoSphereVert from '../shaders/atmosphere/atmosphere_vert.glsl'; + interface IAtmoSphereLayerStyleOptions { opacity: number; } const { isNumber } = lodashUtil; export default class EarthAtomSphereModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + NORMAL: 9, + UV: 10, + }); + } + protected getCommonUniformsInfo(): { uniformsArray: number[]; uniformsLength: number; @@ -41,6 +49,7 @@ export default class EarthAtomSphereModel extends BaseModel { moduleName: 'earthAtmoSphere', vertexShader: atmoSphereVert, fragmentShader: atmoSphereFrag, + defines: this.getDefines(), triangulation: earthTriangulation, depth: { enable: false }, blend: this.getBlend(), @@ -50,31 +59,31 @@ export default class EarthAtomSphereModel extends BaseModel { protected registerBuiltinAttributes() { // point layer size; - this.styleAttributeService.registerStyleAttribute({ - name: 'size', - type: AttributeType.Attribute, - descriptor: { - name: 'a_Size', - shaderLocation: ShaderLocation.SIZE, - buffer: { - usage: gl.DYNAMIC_DRAW, - data: [], - type: gl.FLOAT, - }, - size: 1, - update: (feature: IEncodeFeature) => { - const { size = 1 } = feature; - return Array.isArray(size) ? [size[0]] : [size as number]; - }, - }, - }); + // this.styleAttributeService.registerStyleAttribute({ + // name: 'size', + // type: AttributeType.Attribute, + // descriptor: { + // name: 'a_Size', + // shaderLocation: this.attributeLocation.SIZE, + // buffer: { + // usage: gl.DYNAMIC_DRAW, + // data: [], + // type: gl.FLOAT, + // }, + // size: 1, + // update: (feature: IEncodeFeature) => { + // const { size = 1 } = feature; + // return Array.isArray(size) ? [size[0]] : [size as number]; + // }, + // }, + // }); this.styleAttributeService.registerStyleAttribute({ name: 'normal', type: AttributeType.Attribute, descriptor: { name: 'a_Normal', - shaderLocation: ShaderLocation.NORMAL, + shaderLocation: this.attributeLocation.NORMAL, buffer: { usage: gl.STATIC_DRAW, data: [], @@ -98,7 +107,7 @@ export default class EarthAtomSphereModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Uv', - shaderLocation: ShaderLocation.UV, + shaderLocation: this.attributeLocation.UV, buffer: { usage: gl.DYNAMIC_DRAW, data: [], diff --git a/packages/layers/src/earth/models/base.ts b/packages/layers/src/earth/models/base.ts index 1c43ffc09ed..7685a4fbcef 100644 --- a/packages/layers/src/earth/models/base.ts +++ b/packages/layers/src/earth/models/base.ts @@ -4,11 +4,18 @@ import { AttributeType, gl } from '@antv/l7-core'; import BaseModel from '../../core/BaseModel'; import { earthTriangulation } from '../../core/triangulation'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import baseFrag from '../shaders/base/base_frag.glsl'; import baseVert from '../shaders/base/base_vert.glsl'; export default class BaseEarthModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + NORMAL: 9, + UV: 10, + }); + } + protected texture: ITexture2D; // T: 当前的地球时间 - 控制太阳的方位 private earthTime: number = 3.4; @@ -95,6 +102,7 @@ export default class BaseEarthModel extends BaseModel { moduleName: 'earthBase', vertexShader: baseVert, fragmentShader: baseFrag, + defines: this.getDefines(), triangulation: earthTriangulation, depth: { enable: true }, blend: this.getBlend(), @@ -103,31 +111,31 @@ export default class BaseEarthModel extends BaseModel { } protected registerBuiltinAttributes() { - this.styleAttributeService.registerStyleAttribute({ - name: 'size', - type: AttributeType.Attribute, - descriptor: { - name: 'a_Size', - shaderLocation: ShaderLocation.SIZE, - buffer: { - usage: gl.DYNAMIC_DRAW, - data: [], - type: gl.FLOAT, - }, - size: 1, - update: (feature: IEncodeFeature) => { - const { size = 1 } = feature; - return Array.isArray(size) ? [size[0]] : [size as number]; - }, - }, - }); + // this.styleAttributeService.registerStyleAttribute({ + // name: 'size', + // type: AttributeType.Attribute, + // descriptor: { + // name: 'a_Size', + // shaderLocation: this.attributeLocation.SIZE, + // buffer: { + // usage: gl.DYNAMIC_DRAW, + // data: [], + // type: gl.FLOAT, + // }, + // size: 1, + // update: (feature: IEncodeFeature) => { + // const { size = 1 } = feature; + // return Array.isArray(size) ? [size[0]] : [size as number]; + // }, + // }, + // }); this.styleAttributeService.registerStyleAttribute({ name: 'normal', type: AttributeType.Attribute, descriptor: { name: 'a_Normal', - shaderLocation: ShaderLocation.NORMAL, + shaderLocation: this.attributeLocation.NORMAL, buffer: { usage: gl.STATIC_DRAW, data: [], @@ -151,7 +159,7 @@ export default class BaseEarthModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Uv', - shaderLocation: ShaderLocation.UV, + shaderLocation: this.attributeLocation.UV, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, diff --git a/packages/layers/src/earth/models/bloomsphere.ts b/packages/layers/src/earth/models/bloomsphere.ts index 01736058c1a..b189c6e7e10 100644 --- a/packages/layers/src/earth/models/bloomsphere.ts +++ b/packages/layers/src/earth/models/bloomsphere.ts @@ -3,7 +3,6 @@ import { AttributeType, gl } from '@antv/l7-core'; import { lodashUtil } from '@antv/l7-utils'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import { earthOuterTriangulation } from '../../core/triangulation'; import bloomSphereFrag from '../shaders/bloomshpere/bloomsphere_frag.glsl'; import bloomSphereVert from '../shaders/bloomshpere/bloomsphere_vert.glsl'; @@ -12,6 +11,14 @@ interface IBloomLayerStyleOptions { } const { isNumber } = lodashUtil; export default class EarthBloomSphereModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + NORMAL: 9, + UV: 10, + }); + } + protected getCommonUniformsInfo(): { uniformsArray: number[]; uniformsLength: number; @@ -41,6 +48,7 @@ export default class EarthBloomSphereModel extends BaseModel { moduleName: 'earthBloom', vertexShader: bloomSphereVert, fragmentShader: bloomSphereFrag, + defines: this.getDefines(), triangulation: earthOuterTriangulation, depth: { enable: false }, blend: this.getBlend(), @@ -49,31 +57,31 @@ export default class EarthBloomSphereModel extends BaseModel { } protected registerBuiltinAttributes() { - this.styleAttributeService.registerStyleAttribute({ - name: 'size', - type: AttributeType.Attribute, - descriptor: { - name: 'a_Size', - shaderLocation: ShaderLocation.SIZE, - buffer: { - usage: gl.DYNAMIC_DRAW, - data: [], - type: gl.FLOAT, - }, - size: 1, - update: (feature: IEncodeFeature) => { - const { size = 1 } = feature; - return Array.isArray(size) ? [size[0]] : [size as number]; - }, - }, - }); + // this.styleAttributeService.registerStyleAttribute({ + // name: 'size', + // type: AttributeType.Attribute, + // descriptor: { + // name: 'a_Size', + // shaderLocation: this.attributeLocation.SIZE, + // buffer: { + // usage: gl.DYNAMIC_DRAW, + // data: [], + // type: gl.FLOAT, + // }, + // size: 1, + // update: (feature: IEncodeFeature) => { + // const { size = 1 } = feature; + // return Array.isArray(size) ? [size[0]] : [size as number]; + // }, + // }, + // }); this.styleAttributeService.registerStyleAttribute({ name: 'normal', type: AttributeType.Attribute, descriptor: { name: 'a_Normal', - shaderLocation: ShaderLocation.NORMAL, + shaderLocation: this.attributeLocation.NORMAL, buffer: { usage: gl.STATIC_DRAW, data: [], @@ -97,7 +105,7 @@ export default class EarthBloomSphereModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Uv', - shaderLocation: ShaderLocation.UV, + shaderLocation: this.attributeLocation.UV, buffer: { usage: gl.DYNAMIC_DRAW, data: [], diff --git a/packages/layers/src/earth/shaders/atmosphere/atmosphere_vert.glsl b/packages/layers/src/earth/shaders/atmosphere/atmosphere_vert.glsl index fa995a18ba9..712e89fb9bb 100644 --- a/packages/layers/src/earth/shaders/atmosphere/atmosphere_vert.glsl +++ b/packages/layers/src/earth/shaders/atmosphere/atmosphere_vert.glsl @@ -1,10 +1,12 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 1) vec4 a_Color; -layout(location = 13) in vec3 a_Normal; -layout(location = 14) in vec2 a_Uv; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_COLOR) vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_NORMAL) in vec3 a_Normal; +layout(location = ATTRIBUTE_LOCATION_UV) in vec2 a_Uv; + layout(std140) uniform commonUniforms { float u_opacity; }; + #pragma include "scene_uniforms" out vec3 vVertexNormal; out vec4 v_Color; @@ -12,7 +14,7 @@ out float v_offset; void main() { float EARTH_RADIUS = 100.0; - + v_Color = a_Color; v_offset = min(((length(u_CameraPosition) - EARTH_RADIUS)/600.0) * 0.5 + 0.4, 1.0); diff --git a/packages/layers/src/earth/shaders/base/base_vert.glsl b/packages/layers/src/earth/shaders/base/base_vert.glsl index 0837a31ad1d..bd49df4ce50 100644 --- a/packages/layers/src/earth/shaders/base/base_vert.glsl +++ b/packages/layers/src/earth/shaders/base/base_vert.glsl @@ -1,7 +1,7 @@ // attribute vec4 a_Color; -layout(location = 0) in vec3 a_Position; -layout(location = 13) in vec3 a_Normal; -layout(location = 14) in vec2 a_Uv; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_NORMAL) in vec3 a_Normal; +layout(location = ATTRIBUTE_LOCATION_UV) in vec2 a_Uv; // attribute vec2 a_Extrude; // attribute float a_Size; diff --git a/packages/layers/src/earth/shaders/bloomshpere/bloomsphere_vert.glsl b/packages/layers/src/earth/shaders/bloomshpere/bloomsphere_vert.glsl index f2ea5ad3bd9..401ebf9ecc6 100644 --- a/packages/layers/src/earth/shaders/bloomshpere/bloomsphere_vert.glsl +++ b/packages/layers/src/earth/shaders/bloomshpere/bloomsphere_vert.glsl @@ -1,7 +1,8 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 1) vec4 a_Color; -layout(location = 13) in vec3 a_Normal; -layout(location = 14) in vec2 a_Uv; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_COLOR) vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_NORMAL) in vec3 a_Normal; +layout(location = ATTRIBUTE_LOCATION_UV) in vec2 a_Uv; + layout(std140) uniform commonUniforms { float u_opacity; }; diff --git a/packages/layers/src/geometry/models/billboard.ts b/packages/layers/src/geometry/models/billboard.ts index b6d00311ef8..56c848b6f82 100644 --- a/packages/layers/src/geometry/models/billboard.ts +++ b/packages/layers/src/geometry/models/billboard.ts @@ -1,12 +1,19 @@ import type { IEncodeFeature, IModel, IModelUniform, ITexture2D } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import type { IGeometryLayerStyleOptions } from '../../core/interface'; import planeFrag from '../shaders/billboard_frag.glsl'; import planeVert from '../shaders/billboard_vert.glsl'; export default class BillBoardModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + EXTRUDE: 9, + UV: 10, + }); + } + protected texture: ITexture2D; private radian: number = 0; // 旋转的弧度 @@ -52,12 +59,11 @@ export default class BillBoardModel extends BaseModel { /** * rotateFlag * DEFAULT 1 - * MAPBOX 1 - * GAODE2.x -1 - * GAODE1.x -1 + * MAPBOX 1 + * AMAP -1 */ let rotateFlag = 1; - if (this.mapService.version === 'GAODE2.x' || this.mapService.version === 'GAODE1.x') { + if (this.mapService.getType() === 'amap') { rotateFlag = -1; } // 控制图标的旋转角度(绕 Z 轴旋转) @@ -97,6 +103,7 @@ export default class BillBoardModel extends BaseModel { vertexShader: planeVert, fragmentShader: planeFrag, triangulation: this.planeGeometryTriangulation, + defines: this.getDefines(), inject: this.getInject(), primitive: gl.TRIANGLES, depth: { enable: true }, @@ -136,7 +143,7 @@ export default class BillBoardModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Extrude', - shaderLocation: ShaderLocation.EXTRUDE, + shaderLocation: this.attributeLocation.EXTRUDE, buffer: { usage: gl.DYNAMIC_DRAW, data: [], @@ -160,7 +167,7 @@ export default class BillBoardModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Uv', - shaderLocation: ShaderLocation.UV, + shaderLocation: this.attributeLocation.UV, buffer: { usage: gl.DYNAMIC_DRAW, data: [], diff --git a/packages/layers/src/geometry/models/plane.ts b/packages/layers/src/geometry/models/plane.ts index 5f6610d0130..86d60108f7b 100644 --- a/packages/layers/src/geometry/models/plane.ts +++ b/packages/layers/src/geometry/models/plane.ts @@ -1,19 +1,18 @@ -import type { - IAttributeAndElements, - IEncodeFeature, - IModel, - IModelUniform, - ITexture2D, -} from '@antv/l7-core'; +import type { IEncodeFeature, IModel, IModelUniform, ITexture2D } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; -// import { mat4, vec3 } from 'gl-matrix'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import type { IGeometryLayerStyleOptions } from '../../core/interface'; import planeFrag from '../shaders/plane_frag.glsl'; import planeVert from '../shaders/plane_vert.glsl'; export default class PlaneModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + UV: 10, + }); + } + protected texture: ITexture2D; protected terrainImage: HTMLImageElement; protected terrainImageLoaded: boolean = false; @@ -48,14 +47,7 @@ export default class PlaneModel extends BaseModel { for (let ix = 0; ix < gridX1; ix++) { const x = ix * segmentWidth - widthHalf; - if (this.mapService.version === 'GAODE2.x') { - // @ts-ignore - const [a, b] = this.mapService.lngLatToCoord([x + lng, -y + lat]) as [number, number]; - positions.push(a, b, 0); - } else { - positions.push(x + lng, -y + lat, 0); - } - + positions.push(x + lng, -y + lat, 0); positions.push(ix / gridX); positions.push(1 - iy / gridY); } @@ -84,6 +76,7 @@ export default class PlaneModel extends BaseModel { heightSegments = 1, center = [120, 30], terrainTexture, + rgb2height = (r: number, g: number, b: number) => r + g + b, } = this.layer.getLayerConfig() as IGeometryLayerStyleOptions; const { indices, positions } = this.initPlane( width, @@ -94,7 +87,14 @@ export default class PlaneModel extends BaseModel { ); if (terrainTexture) { // 存在地形贴图的时候会根据地形贴图对顶点进行偏移 - this.loadTerrainTexture(positions, indices); + return this.translateVertex( + positions, + indices, + this.terrainImage, + widthSegments, + heightSegments, + rgb2height, + ); } return { @@ -148,7 +148,8 @@ export default class PlaneModel extends BaseModel { } public async initModels(): Promise { - const { mapTexture } = this.layer.getLayerConfig() as IGeometryLayerStyleOptions; + const { mapTexture, terrainTexture } = + this.layer.getLayerConfig() as IGeometryLayerStyleOptions; this.mapTexture = mapTexture; const { createTexture2D } = this.rendererService; @@ -160,11 +161,16 @@ export default class PlaneModel extends BaseModel { this.updateTexture(mapTexture); this.initUniformsBuffer(); + if (terrainTexture) { + this.terrainImage = await this.loadTerrainImage(terrainTexture); + } + const model = await this.layer.buildLayerModel({ moduleName: 'geometryPlane', vertexShader: planeVert, fragmentShader: planeFrag, triangulation: this.planeGeometryTriangulation, + defines: this.getDefines(), inject: this.getInject(), primitive: gl.TRIANGLES, depth: { enable: true }, @@ -282,70 +288,38 @@ export default class PlaneModel extends BaseModel { } } - const oldFeatures = this.layer.getEncodedData(); - const modelData = this.styleAttributeService.createAttributesAndIndices(oldFeatures, () => { - return { - vertices: positions, - indices, - size: 5, - }; - }); - this.layer.updateModelData(modelData as IAttributeAndElements); - this.layerService.throttleRenderLayers(); + return { + vertices: positions, + indices, + size: 5, + }; } - /** - * load terrain texture & offset attribute z - */ - protected loadTerrainTexture(positions: number[], indices: number[]) { - const { - widthSegments = 1, - heightSegments = 1, - terrainTexture, - rgb2height = (r: number, g: number, b: number) => r + g + b, - } = this.layer.getLayerConfig() as IGeometryLayerStyleOptions; + private async loadTerrainImage(terrainTexture: string) { if (this.terrainImage) { // 若当前已经存在 image,直接进行偏移计算(LOD) if (this.terrainImageLoaded) { - this.translateVertex( - positions, - indices, - this.terrainImage, - widthSegments, - heightSegments, - rgb2height, - ); + return this.terrainImage; } else { - this.terrainImage.onload = () => { - this.translateVertex( - positions, - indices, - this.terrainImage, - widthSegments, - heightSegments, - rgb2height, - ); - }; + return new Promise((resolve) => { + this.terrainImage.onload = () => { + resolve(this.terrainImage); + }; + }); } } else { // 加载地形贴图、根据地形贴图对 planeGeometry 进行偏移 const terrainImage = new Image(); - this.terrainImage = terrainImage; terrainImage.crossOrigin = 'anonymous'; - terrainImage.onload = () => { - this.terrainImageLoaded = true; - // 图片加载完,触发事件,可以进行地形图的顶点计算存储 - setTimeout(() => this.layer.emit('terrainImageLoaded', null)); - this.translateVertex( - positions, - indices, - terrainImage, - widthSegments, - heightSegments, - rgb2height, - ); - }; - terrainImage.src = terrainTexture as string; + return new Promise((resolve) => { + terrainImage.onload = () => { + this.terrainImageLoaded = true; + resolve(terrainImage); + // 图片加载完,触发事件,可以进行地形图的顶点计算存储 + setTimeout(() => this.layer.emit('terrainImageLoaded', null)); + }; + terrainImage.src = terrainTexture as string; + }); } } @@ -356,7 +330,7 @@ export default class PlaneModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Uv', - shaderLocation: ShaderLocation.UV, + shaderLocation: this.attributeLocation.UV, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, diff --git a/packages/layers/src/geometry/models/sprite.ts b/packages/layers/src/geometry/models/sprite.ts index a43b5f555ca..48306fcfe46 100644 --- a/packages/layers/src/geometry/models/sprite.ts +++ b/packages/layers/src/geometry/models/sprite.ts @@ -24,7 +24,6 @@ export default class SpriteModel extends BaseModel { public initSprite(radius = 10, spriteCount = 100, lng = 120, lat = 30) { const indices = []; const positions = []; - const mapService = this.mapService; const heightLimit = this.spriteAnimate === SPRITE_ANIMATE_DIR.UP ? -this.spriteTop : this.spriteTop; for (let i = 0; i < spriteCount; i++) { @@ -40,20 +39,15 @@ export default class SpriteModel extends BaseModel { const randomY = radius * Math.random(); const x = -radius / 2 + randomX; const y = -radius / 2 + randomY; - if (mapService.version === 'GAODE2.x') { - // @ts-ignore - const [a, b] = mapService.lngLatToCoord([x + lng, -y + lat]) as [number, number]; - return [a, b, z, 0, 0]; - } else { - return [x + lng, -y + lat, z, 0, 0]; - } + + return [x + lng, -y + lat, z, 0, 0]; } return { indices, positions }; } public planeGeometryUpdateTriangulation = () => { - const { spriteBottom = -100000 } = this.layer.getLayerConfig() as IGeometryLayerStyleOptions; + const { spriteBottom = -10 } = this.layer.getLayerConfig() as IGeometryLayerStyleOptions; const updateZ = this.spriteUpdate; const bottomZ = spriteBottom; const topZ = this.spriteTop; @@ -164,8 +158,8 @@ export default class SpriteModel extends BaseModel { public async initModels(): Promise { const { mapTexture, - spriteTop = 5000000, - spriteUpdate = 10000, + spriteTop = 300, + spriteUpdate = 10, spriteAnimate = SPRITE_ANIMATE_DIR.DOWN, } = this.layer.getLayerConfig() as IGeometryLayerStyleOptions; this.initUniformsBuffer(); @@ -193,6 +187,7 @@ export default class SpriteModel extends BaseModel { vertexShader: spriteVert, fragmentShader: spriteFrag, triangulation: this.planeGeometryTriangulation, + defines: this.getDefines(), inject: this.getInject(), primitive: gl.POINTS, depth: { enable: false }, diff --git a/packages/layers/src/geometry/shaders/billboard_vert.glsl b/packages/layers/src/geometry/shaders/billboard_vert.glsl index 6d58e418dc1..80fe1122aaf 100644 --- a/packages/layers/src/geometry/shaders/billboard_vert.glsl +++ b/packages/layers/src/geometry/shaders/billboard_vert.glsl @@ -1,12 +1,12 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 11) in vec3 a_Extrude; -layout(location = 14) in vec2 a_Uv; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_EXTRUDE) in vec3 a_Extrude; +layout(location = ATTRIBUTE_LOCATION_UV) in vec2 a_Uv; layout(std140) uniform commonUniforms { - vec2 u_size; - float u_raisingHeight; - float u_rotation; - float u_opacity; + vec2 u_size; + float u_raisingHeight; + float u_rotation; + float u_opacity; }; out vec2 v_uv; @@ -15,26 +15,29 @@ out vec2 v_uv; #pragma include "picking" #pragma include "rotation_2d" void main() { - vec3 extrude = a_Extrude; - v_uv = a_Uv; - float raiseHeight = u_raisingHeight; - if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { - float mapboxZoomScale = 4.0/pow(2.0, 21.0 - u_Zoom); - raiseHeight = u_raisingHeight * mapboxZoomScale; - } + vec3 extrude = a_Extrude; + v_uv = a_Uv; + float raiseHeight = u_raisingHeight; + if ( + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET + ) { + float mapboxZoomScale = 4.0 / pow(2.0, 21.0 - u_Zoom); + raiseHeight = u_raisingHeight * mapboxZoomScale; + } - // 计算经纬度点位坐标 - vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0)); + // 计算经纬度点位坐标 + vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0)); - // 计算绕 z 轴旋转后的偏移 - vec2 offsetXY = project_pixel(rotate_matrix(vec2(extrude.x * u_size.x, 0.0),u_rotation)); - // 绕 z 轴旋转 - float x = project_pos.x + offsetXY.x; - float y = project_pos.y + offsetXY.y; - // z 轴不参与旋转 - float z = project_pixel(extrude.y * u_size.y + raiseHeight); + // 计算绕 z 轴旋转后的偏移 + vec2 offsetXY = project_pixel(rotate_matrix(vec2(extrude.x * u_size.x, 0.0), u_rotation)); + // 绕 z 轴旋转 + float x = project_pos.x + offsetXY.x; + float y = project_pos.y + offsetXY.y; + // z 轴不参与旋转 + float z = project_pixel(extrude.y * u_size.y + raiseHeight); - gl_Position = project_common_position_to_clipspace_v2(vec4(x , y, z , 1.0)); + gl_Position = project_common_position_to_clipspace(vec4(x, y, z, 1.0)); - setPickingColor(a_PickingColor); + setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/geometry/shaders/plane_frag.glsl b/packages/layers/src/geometry/shaders/plane_frag.glsl index c12e0bf4280..2c9b97231f1 100644 --- a/packages/layers/src/geometry/shaders/plane_frag.glsl +++ b/packages/layers/src/geometry/shaders/plane_frag.glsl @@ -1,4 +1,3 @@ - uniform sampler2D u_texture; layout(std140) uniform commonUniforms { float u_opacity; @@ -13,12 +12,10 @@ out vec4 outputColor; #pragma include "picking" void main() { - // gl_FragColor = vec4(v_Color, u_opacity); - if(u_mapFlag > 0.0) { + if (u_mapFlag > 0.0) { outputColor = texture(SAMPLER_2D(u_texture), vec2(v_uv.x, 1.0 - v_uv.y)); outputColor.a *= u_opacity; } else { - // gl_FragColor = vec4(v_uv, 0.0, u_opacity); outputColor = vec4(v_Color, u_opacity); } outputColor.a *= v_clip; diff --git a/packages/layers/src/geometry/shaders/plane_vert.glsl b/packages/layers/src/geometry/shaders/plane_vert.glsl index 03b752467c2..7d921f0de4b 100644 --- a/packages/layers/src/geometry/shaders/plane_vert.glsl +++ b/packages/layers/src/geometry/shaders/plane_vert.glsl @@ -1,7 +1,6 @@ - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec3 a_Color; -layout(location = 14) in vec2 a_Uv; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec3 a_Color; +layout(location = ATTRIBUTE_LOCATION_UV) in vec2 a_Uv; layout(std140) uniform commonUniforms { float u_opacity; @@ -16,17 +15,17 @@ out float v_clip; #pragma include "projection" #pragma include "picking" void main() { - v_Color = a_Color; - v_uv = a_Uv; - - vec4 project_pos = project_position(vec4(a_Position, 1.0)); + v_Color = a_Color; + v_uv = a_Uv; + + vec4 project_pos = project_position(vec4(a_Position, 1.0)); + + v_clip = 1.0; + if (a_Position.z < u_terrainClipHeight) { + v_clip = 0.0; + } - v_clip = 1.0; - if(a_Position.z < u_terrainClipHeight) { - v_clip = 0.0; - } - - gl_Position = project_common_position_to_clipspace_v2(vec4(project_pos.xy, a_Position.z, 1.0)); + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy, a_Position.z, 1.0)); - setPickingColor(a_PickingColor); + setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/geometry/shaders/sprite_vert.glsl b/packages/layers/src/geometry/shaders/sprite_vert.glsl index 77e8fbbdaa7..c91d9c4a30d 100644 --- a/packages/layers/src/geometry/shaders/sprite_vert.glsl +++ b/packages/layers/src/geometry/shaders/sprite_vert.glsl @@ -1,5 +1,5 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec3 a_Color; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec3 a_Color; layout(std140) uniform commonUniforms { float u_opacity; @@ -12,12 +12,10 @@ out float v_d; #pragma include "projection" void main() { - v_Color = a_Color.xyz; - - vec4 project_pos = project_position(vec4(a_Position, 1.0)); + v_Color = a_Color.xyz; + v_d = a_Position.z; - v_d = a_Position.z; - - gl_Position = project_common_position_to_clipspace_v2(vec4(project_pos.xy, a_Position.z, 1.0)); -gl_PointSize = pow((u_Zoom - 1.0), 2.0) * u_Scale; + vec4 project_pos = project_position(vec4(a_Position, 1.0)); + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy, a_Position.z, 1.0)); + gl_PointSize = pow(u_Zoom - 1.0, 2.0) * u_Scale; } diff --git a/packages/layers/src/heatmap/models/grid.ts b/packages/layers/src/heatmap/models/grid.ts index db72882ceac..b8ac5548c5d 100644 --- a/packages/layers/src/heatmap/models/grid.ts +++ b/packages/layers/src/heatmap/models/grid.ts @@ -6,6 +6,13 @@ import { HeatmapGridTriangulation } from '../../core/triangulation'; import grid_frag from '../shaders/grid/grid_frag.glsl'; import grid_vert from '../shaders/grid/grid_vert.glsl'; export default class GridModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + POS: 9, + }); + } + public getUninforms(): IModelUniform { const commoninfo = this.getCommonUniformsInfo(); const attributeInfo = this.getUniformsBufferInfo(this.getStyleAttribute()); @@ -43,6 +50,7 @@ export default class GridModel extends BaseModel { moduleName: 'heatmapGrid', vertexShader: grid_vert, fragmentShader: grid_frag, + defines: this.getDefines(), triangulation: HeatmapGridTriangulation, primitive: gl.TRIANGLES, depth: { enable: false }, @@ -54,7 +62,7 @@ export default class GridModel extends BaseModel { name: 'pos', // 顶点经纬度位置 type: AttributeType.Attribute, descriptor: { - shaderLocation: 10, + shaderLocation: this.attributeLocation.POS, name: 'a_Pos', buffer: { usage: gl.DYNAMIC_DRAW, @@ -63,9 +71,7 @@ export default class GridModel extends BaseModel { }, size: 3, update: (feature: IEncodeFeature) => { - const coordinates = ( - feature.version === 'GAODE2.x' ? feature.originCoordinates : feature.coordinates - ) as number[]; + const coordinates = feature.coordinates as number[]; return [coordinates[0], coordinates[1], 0]; }, }, diff --git a/packages/layers/src/heatmap/models/grid3d.ts b/packages/layers/src/heatmap/models/grid3d.ts index c78be6b780c..bb95e84847f 100644 --- a/packages/layers/src/heatmap/models/grid3d.ts +++ b/packages/layers/src/heatmap/models/grid3d.ts @@ -1,12 +1,20 @@ import type { IEncodeFeature, IModel, IModelUniform } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import type { IHeatMapLayerStyleOptions } from '../../core/interface'; import { PointExtrudeTriangulation } from '../../core/triangulation'; import grid_3d_frag from '../shaders/grid3d/grid_3d_frag.glsl'; import grid_3d_vert from '../shaders/grid3d/grid_3d_vert.glsl'; export default class Grid3DModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + SIZE: 9, + POS: 10, + NORMAL: 11, + }); + } + public getUninforms(): IModelUniform { const commoninfo = this.getCommonUniformsInfo(); const attributeInfo = this.getUniformsBufferInfo(this.getStyleAttribute()); @@ -44,6 +52,7 @@ export default class Grid3DModel extends BaseModel { moduleName: 'heatmapGrid3d', vertexShader: grid_3d_vert, fragmentShader: grid_3d_frag, + defines: this.getDefines(), triangulation: PointExtrudeTriangulation, primitive: gl.TRIANGLES, depth: { enable: true }, @@ -55,7 +64,7 @@ export default class Grid3DModel extends BaseModel { name: 'size', type: AttributeType.Attribute, descriptor: { - shaderLocation: ShaderLocation.SIZE, + shaderLocation: this.attributeLocation.SIZE, name: 'a_Size', buffer: { usage: gl.DYNAMIC_DRAW, @@ -75,7 +84,7 @@ export default class Grid3DModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Normal', - shaderLocation: ShaderLocation.NORMAL, + shaderLocation: this.attributeLocation.NORMAL, buffer: { usage: gl.STATIC_DRAW, data: [], @@ -98,7 +107,7 @@ export default class Grid3DModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Pos', - shaderLocation: 10, + shaderLocation: this.attributeLocation.POS, buffer: { usage: gl.DYNAMIC_DRAW, data: [], @@ -106,9 +115,7 @@ export default class Grid3DModel extends BaseModel { }, size: 3, update: (feature: IEncodeFeature) => { - const coordinates = ( - feature.version === 'GAODE2.x' ? feature.originCoordinates : feature.coordinates - ) as number[]; + const coordinates = feature.coordinates as number[]; return [coordinates[0], coordinates[1], 0]; }, }, diff --git a/packages/layers/src/heatmap/models/heatmap.ts b/packages/layers/src/heatmap/models/heatmap.ts index bd8f53a53e7..eb55f695dca 100644 --- a/packages/layers/src/heatmap/models/heatmap.ts +++ b/packages/layers/src/heatmap/models/heatmap.ts @@ -9,7 +9,7 @@ import type { } from '@antv/l7-core'; import { AttributeType, TextureUsage, gl } from '@antv/l7-core'; import type { IColorRamp } from '@antv/l7-utils'; -import { generateColorRamp, getCullFace, lodashUtil } from '@antv/l7-utils'; +import { generateColorRamp, lodashUtil } from '@antv/l7-utils'; import { mat4 } from 'gl-matrix'; import BaseModel from '../../core/BaseModel'; import type { IHeatMapLayerStyleOptions } from '../../core/interface'; @@ -21,13 +21,21 @@ import heatmap_3d_vert from '../shaders/heatmap/heatmap_3d_vert.glsl'; import heatmap_frag from '../shaders/heatmap/heatmap_frag.glsl'; import heatmap_vert from '../shaders/heatmap/heatmap_vert.glsl'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import heatmap_framebuffer_frag from '../shaders/heatmap/heatmap_framebuffer_frag.glsl'; import heatmap_framebuffer_vert from '../shaders/heatmap/heatmap_framebuffer_vert.glsl'; import { heatMap3DTriangulation } from '../triangulation'; const { isEqual } = lodashUtil; export default class HeatMapModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + SIZE: 9, + UV: 10, + DIR: 11, + }); + } + protected texture: ITexture2D; protected colorTexture: ITexture2D; protected heatmapFramerBuffer: IFramebuffer; @@ -112,7 +120,7 @@ export default class HeatMapModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Dir', - shaderLocation: 10, + shaderLocation: this.attributeLocation.DIR, buffer: { usage: gl.DYNAMIC_DRAW, data: [], @@ -130,7 +138,7 @@ export default class HeatMapModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Size', - shaderLocation: ShaderLocation.SIZE, + shaderLocation: this.attributeLocation.SIZE, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, @@ -145,6 +153,10 @@ export default class HeatMapModel extends BaseModel { }, }); } + + /** + * 热力图密度图 + */ private async buildHeatMapIntensity() { this.uniformBuffers = [ this.rendererService.createBuffer({ @@ -159,13 +171,14 @@ export default class HeatMapModel extends BaseModel { vertexShader: heatmap_framebuffer_vert, fragmentShader: heatmap_framebuffer_frag, triangulation: HeatmapTriangulation, + defines: this.getDefines(), depth: { enable: false, }, cull: { enable: true, - face: getCullFace(this.mapService.version), + face: gl.FRONT, }, }); return model; @@ -192,7 +205,7 @@ export default class HeatMapModel extends BaseModel { uniformBuffers: [...this.colorModelUniformBuffer, ...this.rendererService.uniformBuffers], attributes: { a_Position: createAttribute({ - shaderLocation: ShaderLocation.POSITION, + shaderLocation: this.attributeLocation.POSITION, buffer: createBuffer({ data: [-1, 1, 0, 1, 1, 0, -1, -1, 0, 1, -1, 0], type: gl.FLOAT, @@ -200,7 +213,7 @@ export default class HeatMapModel extends BaseModel { size: 3, }), a_Uv: createAttribute({ - shaderLocation: ShaderLocation.UV, + shaderLocation: this.attributeLocation.UV, buffer: createBuffer({ data: [0, 1, 1, 1, 0, 0, 1, 0], type: gl.FLOAT, @@ -221,6 +234,72 @@ export default class HeatMapModel extends BaseModel { }), }); } + + private build3dHeatMap() { + const { getViewportSize } = this.rendererService; + const { width, height } = getViewportSize(); + const triangulation = heatMap3DTriangulation(width / 4.0, height / 4.0); + this.shaderModuleService.registerModule('heatmap3dColor', { + vs: heatmap_3d_vert, + fs: heatmap_3d_frag, + }); + + this.heat3DModelUniformBuffer = [ + this.rendererService.createBuffer({ + // opacity + data: new Float32Array(16 * 2 + 4).fill(0), // 长度需要大于等于 4 + isUBO: true, + }), + ]; + const { vs, fs, uniforms } = this.shaderModuleService.getModule('heatmap3dColor'); + const { createAttribute, createElements, createBuffer, createModel } = this.rendererService; + + return createModel({ + vs, + fs, + attributes: { + a_Position: createAttribute({ + shaderLocation: this.attributeLocation.POSITION, + buffer: createBuffer({ + data: triangulation.vertices, + type: gl.FLOAT, + }), + size: 3, + }), + a_Uv: createAttribute({ + shaderLocation: this.attributeLocation.UV, + buffer: createBuffer({ + data: triangulation.uvs, + type: gl.FLOAT, + }), + size: 2, + }), + }, + primitive: gl.TRIANGLES, + uniformBuffers: [...this.heat3DModelUniformBuffer, ...this.rendererService.uniformBuffers], + uniforms: { + ...uniforms, + }, + depth: { + enable: true, + }, + blend: { + enable: true, + func: { + srcRGB: gl.SRC_ALPHA, + srcAlpha: 1, + dstRGB: gl.ONE_MINUS_SRC_ALPHA, + dstAlpha: 1, + }, + }, + elements: createElements({ + data: triangulation.indices, + type: gl.UNSIGNED_INT, + count: triangulation.indices.length, + }), + }); + } + // 绘制密度图 private drawIntensityMode() { const { intensity = 10, radius = 5 } = this.layer.getLayerConfig() as IHeatMapLayerStyleOptions; @@ -320,70 +399,6 @@ export default class HeatMapModel extends BaseModel { stencil: this.getStencil(options), }); } - private build3dHeatMap() { - const { getViewportSize } = this.rendererService; - const { width, height } = getViewportSize(); - const triangulation = heatMap3DTriangulation(width / 4.0, height / 4.0); - this.shaderModuleService.registerModule('heatmap3dColor', { - vs: heatmap_3d_vert, - fs: heatmap_3d_frag, - }); - - this.heat3DModelUniformBuffer = [ - this.rendererService.createBuffer({ - // opacity - data: new Float32Array(16 * 2 + 4).fill(0), // 长度需要大于等于 4 - isUBO: true, - }), - ]; - const { vs, fs, uniforms } = this.shaderModuleService.getModule('heatmap3dColor'); - const { createAttribute, createElements, createBuffer, createModel } = this.rendererService; - - return createModel({ - vs, - fs, - attributes: { - a_Position: createAttribute({ - shaderLocation: ShaderLocation.POSITION, - buffer: createBuffer({ - data: triangulation.vertices, - type: gl.FLOAT, - }), - size: 3, - }), - a_Uv: createAttribute({ - shaderLocation: ShaderLocation.UV, - buffer: createBuffer({ - data: triangulation.uvs, - type: gl.FLOAT, - }), - size: 2, - }), - }, - primitive: gl.TRIANGLES, - uniformBuffers: [...this.heat3DModelUniformBuffer, ...this.rendererService.uniformBuffers], - uniforms: { - ...uniforms, - }, - depth: { - enable: true, - }, - blend: { - enable: true, - func: { - srcRGB: gl.SRC_ALPHA, - srcAlpha: 1, - dstRGB: gl.ONE_MINUS_SRC_ALPHA, - dstAlpha: 1, - }, - }, - elements: createElements({ - data: triangulation.indices, - type: gl.UNSIGNED_INT, - count: triangulation.indices.length, - }), - }); - } private updateColorTexture() { const { createTexture2D } = this.rendererService; diff --git a/packages/layers/src/heatmap/models/hexagon.ts b/packages/layers/src/heatmap/models/hexagon.ts index c29e6d2eaf3..32b0b56e692 100644 --- a/packages/layers/src/heatmap/models/hexagon.ts +++ b/packages/layers/src/heatmap/models/hexagon.ts @@ -7,6 +7,13 @@ import hexagon_frag from '../shaders/hexagon/hexagon_frag.glsl'; import hexagon_vert from '../shaders/hexagon/hexagon_vert.glsl'; export default class HexagonModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + POS: 9, + }); + } + public getUninforms(): IModelUniform { const commoninfo = this.getCommonUniformsInfo(); const attributeInfo = this.getUniformsBufferInfo(this.getStyleAttribute()); @@ -44,6 +51,7 @@ export default class HexagonModel extends BaseModel { moduleName: 'heatmapHexagon', vertexShader: hexagon_vert, fragmentShader: hexagon_frag, + defines: this.getDefines(), triangulation: HeatmapGridTriangulation, depth: { enable: false }, primitive: gl.TRIANGLES, @@ -56,7 +64,7 @@ export default class HexagonModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Pos', - shaderLocation: 10, + shaderLocation: this.attributeLocation.POS, buffer: { usage: gl.DYNAMIC_DRAW, data: [], @@ -64,9 +72,7 @@ export default class HexagonModel extends BaseModel { }, size: 3, update: (feature: IEncodeFeature) => { - const coordinates = ( - feature.version === 'GAODE2.x' ? feature.originCoordinates : feature.coordinates - ) as number[]; + const coordinates = feature.coordinates as number[]; return [coordinates[0], coordinates[1], 0]; }, }, diff --git a/packages/layers/src/heatmap/shaders/grid/grid_vert.glsl b/packages/layers/src/heatmap/shaders/grid/grid_vert.glsl index 35f949391dd..49519657b6c 100644 --- a/packages/layers/src/heatmap/shaders/grid/grid_vert.glsl +++ b/packages/layers/src/heatmap/shaders/grid/grid_vert.glsl @@ -1,42 +1,30 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 10) in vec3 a_Pos; - -layout(std140) uniform commonUniforms { - vec2 u_radius; - float u_opacity; - float u_coverage; - float u_angle; -}; - - -out vec4 v_color; - - -#pragma include "projection" -#pragma include "project" -#pragma include "picking" - -void main() { - v_color = a_Color; - v_color.a *= u_opacity; - - mat2 rotationMatrix = mat2(cos(u_angle), sin(u_angle), -sin(u_angle), cos(u_angle)); - vec2 offset = a_Position.xy * u_radius * rotationMatrix * u_coverage ; - // vec2 lnglat = unProjectFlat(a_Pos.xy + offset); - // vec4 project_pos = project_position(vec4(lnglat, 0, 1.0)); - // gl_Position = project_common_position_to_clipspace(project_pos); - - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x - vec2 lnglat = unProjectFlat(a_Pos.xy + offset); - vec2 customLnglat = customProject(lnglat) - u_sceneCenterMercator; // 将经纬度转换为高德2.0需要的平面坐标 - vec4 project_pos = project_position(vec4(customLnglat, 0, 1.0)); - gl_Position = u_Mvp * (project_pos); - } else { - vec2 lnglat = unProjectFlat(a_Pos.xy + offset); - vec4 project_pos = project_position(vec4(lnglat, 0, 1.0)); - gl_Position = project_common_position_to_clipspace(project_pos); - } - - setPickingColor(a_PickingColor); -} +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_POS) in vec3 a_Pos; + +layout(std140) uniform commonUniforms { + vec2 u_radius; + float u_opacity; + float u_coverage; + float u_angle; +}; + +out vec4 v_color; + +#pragma include "projection" +#pragma include "project" +#pragma include "picking" + +void main() { + v_color = a_Color; + v_color.a *= u_opacity; + + mat2 rotationMatrix = mat2(cos(u_angle), sin(u_angle), -sin(u_angle), cos(u_angle)); + vec2 offset = a_Position.xy * u_radius * rotationMatrix * u_coverage; + + vec2 lnglat = unProjectFlat(a_Pos.xy + offset); + vec4 project_pos = project_position(vec4(lnglat, 0, 1.0)); + gl_Position = project_common_position_to_clipspace(project_pos); + + setPickingColor(a_PickingColor); +} diff --git a/packages/layers/src/heatmap/shaders/grid3d/grid_3d_vert.glsl b/packages/layers/src/heatmap/shaders/grid3d/grid_3d_vert.glsl index 8225f654cea..28d2f47354e 100644 --- a/packages/layers/src/heatmap/shaders/grid3d/grid_3d_vert.glsl +++ b/packages/layers/src/heatmap/shaders/grid3d/grid_3d_vert.glsl @@ -1,8 +1,8 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in float a_Size; -layout(location = 10) in vec3 a_Pos; -layout(location = 13) in vec3 a_Normal; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in float a_Size; +layout(location = ATTRIBUTE_LOCATION_POS) in vec3 a_Pos; +layout(location = ATTRIBUTE_LOCATION_NORMAL) in vec3 a_Normal; layout(std140) uniform commonUniforms { vec2 u_radius; @@ -20,27 +20,15 @@ out vec4 v_color; void main() { mat2 rotationMatrix = mat2(cos(u_angle), sin(u_angle), -sin(u_angle), cos(u_angle)); - vec2 offset =(vec2(a_Position.xy * u_radius * rotationMatrix * u_coverage)); - - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x - - vec2 lnglat = unProjectFlat(a_Pos.xy + offset); // 经纬度 - vec2 customLnglat = customProject(lnglat) - u_sceneCenterMercator; // 将经纬度转换为高德2.0需要的平面坐标 - vec4 project_pos = project_position(vec4(customLnglat, a_Position.z * a_Size, 1.0)); - - float lightWeight = calc_lighting(project_pos); - v_color =vec4(a_Color.rgb*lightWeight, a_Color.w * u_opacity); - - gl_Position = u_Mvp * vec4(customLnglat , a_Position.z * a_Size, 1.0); - } else { - vec2 lnglat = unProjectFlat(a_Pos.xy + offset); // 实际的经纬度 - vec4 project_pos = project_position(vec4(lnglat, a_Position.z * a_Size, 1.0)); - - float lightWeight = calc_lighting(project_pos); - v_color =vec4(a_Color.rgb*lightWeight, a_Color.w); - - gl_Position = project_common_position_to_clipspace(project_pos); - } + vec2 offset = vec2(a_Position.xy * u_radius * rotationMatrix * u_coverage); + + vec2 lnglat = unProjectFlat(a_Pos.xy + offset); // 实际的经纬度 + vec4 project_pos = project_position(vec4(lnglat, a_Position.z * a_Size, 1.0)); + + float lightWeight = calc_lighting(project_pos); + v_color = vec4(a_Color.rgb * lightWeight, a_Color.w); + + gl_Position = project_common_position_to_clipspace(project_pos); setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/heatmap/shaders/heatmap/heatmap_3d_vert.glsl b/packages/layers/src/heatmap/shaders/heatmap/heatmap_3d_vert.glsl index c523b491008..4c4741e74d3 100644 --- a/packages/layers/src/heatmap/shaders/heatmap/heatmap_3d_vert.glsl +++ b/packages/layers/src/heatmap/shaders/heatmap/heatmap_3d_vert.glsl @@ -1,5 +1,5 @@ layout(location = 0) in vec3 a_Position; -layout(location = 14) in vec2 a_Uv; +layout(location = 10) in vec2 a_Uv; layout(std140) uniform commonUniforms { mat4 u_ViewProjectionMatrixUncentered; @@ -17,13 +17,16 @@ out vec2 v_texCoord; out float v_intensity; vec2 toBezier(float t, vec2 P0, vec2 P1, vec2 P2, vec2 P3) { - float t2 = t * t; - float one_minus_t = 1.0 - t; - float one_minus_t2 = one_minus_t * one_minus_t; - return (P0 * one_minus_t2 * one_minus_t + P1 * 3.0 * t * one_minus_t2 + P2 * 3.0 * t2 * one_minus_t + P3 * t2 * t); + float t2 = t * t; + float one_minus_t = 1.0 - t; + float one_minus_t2 = one_minus_t * one_minus_t; + return P0 * one_minus_t2 * one_minus_t + + P1 * 3.0 * t * one_minus_t2 + + P2 * 3.0 * t2 * one_minus_t + + P3 * t2 * t; } -vec2 toBezier(float t, vec4 p){ - return toBezier(t, vec2(0.0, 0.0), vec2(p.x, p.y), vec2(p.z, p.w), vec2(1.0, 1.0)); +vec2 toBezier(float t, vec4 p) { + return toBezier(t, vec2(0.0, 0.0), vec2(p.x, p.y), vec2(p.z, p.w), vec2(1.0, 1.0)); } #pragma include "projection" @@ -35,22 +38,22 @@ void main() { vec2 pos = a_Uv * vec2(2.0) - vec2(1.0); // 将原本 0 -> 1 的 uv 转换为 -1 -> 1 的标准坐标空间(NDC) vec4 p1 = vec4(pos, 0.0, 1.0); // x/y 平面上的点(z == 0)可以认为是三维上的点被投影到平面后的点 - vec4 p2 = vec4(pos, 1.0, 1.0); // 平行于x/y平面、z==1 的平面上的点 + vec4 p2 = vec4(pos, 1.0, 1.0); // 平行于x/y平面、z==1 的平面上的点 - vec4 inverseP1 = u_InverseViewProjectionMatrix * p1; // 根据视图投影矩阵的逆矩阵平面上的反算出三维空间中的点(p1平面上的点) - vec4 inverseP2 = u_InverseViewProjectionMatrix * p2; + vec4 inverseP1 = u_InverseViewProjectionMatrix * p1; // 根据视图投影矩阵的逆矩阵平面上的反算出三维空间中的点(p1平面上的点) + vec4 inverseP2 = u_InverseViewProjectionMatrix * p2; inverseP1 = inverseP1 / inverseP1.w; // 归一化操作(归一化后为世界坐标) - inverseP2 = inverseP2 / inverseP2.w; + inverseP2 = inverseP2 / inverseP2.w; - float zPos = (0.0 - inverseP1.z) / (inverseP2.z - inverseP1.z); // ?? - vec4 position = inverseP1 + zPos * (inverseP2 - inverseP1); + float zPos = (0.0 - inverseP1.z) / (inverseP2.z - inverseP1.z); // ?? + vec4 position = inverseP1 + zPos * (inverseP2 - inverseP1); - vec4 b= vec4(0.5000, 0.0, 1.0, 0.5000); + vec4 b = vec4(0.5, 0.0, 1.0, 0.5); float fh; v_intensity = texture(SAMPLER_2D(u_texture), v_texCoord).r; fh = toBezier(v_intensity, b).y; - gl_Position = u_ViewProjectionMatrixUncentered * vec4(position.xy, fh * project_pixel(50.), 1.0); - + gl_Position = u_ViewProjectionMatrixUncentered * vec4(position.xy, fh * project_pixel(50.0), 1.0); + } diff --git a/packages/layers/src/heatmap/shaders/heatmap/heatmap_framebuffer_vert.glsl b/packages/layers/src/heatmap/shaders/heatmap/heatmap_framebuffer_vert.glsl index ea8a6600662..6187ff0085e 100644 --- a/packages/layers/src/heatmap/shaders/heatmap/heatmap_framebuffer_vert.glsl +++ b/packages/layers/src/heatmap/shaders/heatmap/heatmap_framebuffer_vert.glsl @@ -1,7 +1,6 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 9) in float a_Size; -layout(location = 10) in vec2 a_Dir; - +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_SIZE) in float a_Size; +layout(location = ATTRIBUTE_LOCATION_DIR) in vec2 a_Dir; layout(std140) uniform commonUniforms { float u_radius; @@ -13,30 +12,25 @@ layout(std140) uniform commonUniforms { out vec2 v_extrude; out float v_weight; -#define GAUSS_COEF 0.3989422804014327 +#define GAUSS_COEF (0.3989422804014327) #pragma include "projection" #pragma include "picking" -void main(){ - vec3 picking_color_placeholder = u_PickingColor; +void main() { + vec3 picking_color_placeholder = u_PickingColor; - v_weight = a_Size; - float ZERO = 1.0 / 255.0 / 16.0; - float extrude_x = a_Dir.x * 2.0 -1.0; - float extrude_y = a_Dir.y * 2.0 -1.0; - vec2 extrude_dir = normalize(vec2(extrude_x,extrude_y)); - float S = sqrt(-2.0 * log(ZERO / a_Size / u_intensity / GAUSS_COEF)) / 2.5; - v_extrude = extrude_dir * S; + v_weight = a_Size; + float ZERO = 1.0 / 255.0 / 16.0; + float extrude_x = a_Dir.x * 2.0 - 1.0; + float extrude_y = a_Dir.y * 2.0 - 1.0; + vec2 extrude_dir = normalize(vec2(extrude_x, extrude_y)); + float S = sqrt(-2.0 * log(ZERO / a_Size / u_intensity / GAUSS_COEF)) / 2.5; + v_extrude = extrude_dir * S; - vec2 offset = project_pixel(v_extrude * u_radius); - vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0)); + vec2 offset = project_pixel(v_extrude * u_radius); + vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0)); - // gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0)); + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0)); - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x - gl_Position = u_Mvp * (vec4(project_pos.xy + offset, 0.0, 1.0)); - } else { - gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0)); - } } diff --git a/packages/layers/src/heatmap/shaders/heatmap/heatmap_vert.glsl b/packages/layers/src/heatmap/shaders/heatmap/heatmap_vert.glsl index 88fc5038451..c0073fec6a5 100644 --- a/packages/layers/src/heatmap/shaders/heatmap/heatmap_vert.glsl +++ b/packages/layers/src/heatmap/shaders/heatmap/heatmap_vert.glsl @@ -1,6 +1,5 @@ - layout(location = 0) in vec3 a_Position; -layout(location = 14) in vec2 a_Uv; +layout(location = 10) in vec2 a_Uv; layout(std140) uniform commonUniforms { float u_opacity; @@ -15,8 +14,8 @@ out vec2 v_texCoord; void main() { v_texCoord = a_Uv; #ifdef VIEWPORT_ORIGIN_TL - v_texCoord.y = 1.0 - v_texCoord.y; + v_texCoord.y = 1.0 - v_texCoord.y; #endif - gl_Position = vec4(a_Position.xy, 0, 1.); + gl_Position = vec4(a_Position.xy, 0, 1.0); } diff --git a/packages/layers/src/heatmap/shaders/hexagon/hexagon_vert.glsl b/packages/layers/src/heatmap/shaders/hexagon/hexagon_vert.glsl index cc7fef95a30..84188d577f4 100644 --- a/packages/layers/src/heatmap/shaders/hexagon/hexagon_vert.glsl +++ b/packages/layers/src/heatmap/shaders/hexagon/hexagon_vert.glsl @@ -1,17 +1,16 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 10) in vec3 a_Pos; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_POS) in vec3 a_Pos; layout(std140) uniform commonUniforms { - vec2 u_radius; - float u_opacity; - float u_coverage; - float u_angle; + vec2 u_radius; + float u_opacity; + float u_coverage; + float u_angle; }; out vec4 v_color; - #pragma include "projection" #pragma include "project" #pragma include "picking" @@ -19,22 +18,13 @@ out vec4 v_color; void main() { v_color = a_Color; v_color.a *= u_opacity; - + mat2 rotationMatrix = mat2(cos(u_angle), sin(u_angle), -sin(u_angle), cos(u_angle)); - vec2 offset =(vec2(a_Position.xy * u_radius * rotationMatrix * u_coverage)); + vec2 offset = vec2(a_Position.xy * u_radius * rotationMatrix * u_coverage); vec2 lnglat = unProjectFlat(a_Pos.xy + offset); - - // vec4 project_pos = project_position(vec4(lnglat, 0, 1.0)); - // gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy, 0., 1.0)); - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x - // gl_Position = u_Mvp * (vec4(project_pos.xy, 0., 1.0)); - // gl_Position = u_Mvp * (vec4(a_Pos.xy + offset, 0., 1.0)); - vec2 customLnglat = customProject(lnglat) - u_sceneCenterMercator; - vec4 project_pos = project_position(vec4(customLnglat, 0, 1.0)); - gl_Position = u_Mvp * vec4(project_pos.xy, 0.0, 1.0); - } else { - vec4 project_pos = project_position(vec4(lnglat, 0, 1.0)); - gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy, 0., 1.0)); - } + + vec4 project_pos = project_position(vec4(lnglat, 0, 1.0)); + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy, 0.0, 1.0)); + setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/image/models/image.ts b/packages/layers/src/image/models/image.ts index 1ffb93f3232..b1e4be64ce6 100644 --- a/packages/layers/src/image/models/image.ts +++ b/packages/layers/src/image/models/image.ts @@ -2,13 +2,19 @@ import type { IEncodeFeature, IModel, ITexture2D } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; import { defaultValue } from '@antv/l7-utils'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import type { IImageLayerStyleOptions } from '../../core/interface'; import { RasterImageTriangulation } from '../../core/triangulation'; import ImageFrag from '../shaders/image_frag.glsl'; import ImageVert from '../shaders/image_vert.glsl'; + export default class ImageModel extends BaseModel { protected texture: ITexture2D; + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + UV: 9, + }); + } protected getCommonUniformsInfo(): { uniformsArray: number[]; @@ -40,10 +46,6 @@ export default class ImageModel extends BaseModel { private async loadTexture() { const { createTexture2D } = this.rendererService; - this.texture = createTexture2D({ - height: 1, - width: 1, - }); const source = this.layer.getSource(); const imageData = await source.data.images; this.texture = createTexture2D({ @@ -61,6 +63,7 @@ export default class ImageModel extends BaseModel { moduleName: 'rasterImage', vertexShader: ImageVert, fragmentShader: ImageFrag, + defines: this.getDefines(), triangulation: RasterImageTriangulation, primitive: gl.TRIANGLES, blend: { @@ -74,12 +77,15 @@ export default class ImageModel extends BaseModel { } protected registerBuiltinAttributes() { + // 注册 Position 属性 64 位地位部分,经纬度数据开启双精度,避免大于 22 层级以上出现数据偏移 + this.registerPosition64LowAttribute(); + this.styleAttributeService.registerStyleAttribute({ name: 'uv', type: AttributeType.Attribute, descriptor: { name: 'a_Uv', - shaderLocation: ShaderLocation.UV, + shaderLocation: this.attributeLocation.UV, buffer: { usage: gl.DYNAMIC_DRAW, data: [], diff --git a/packages/layers/src/image/shaders/image_vert.glsl b/packages/layers/src/image/shaders/image_vert.glsl index dd48895f0c8..e6b1685b6cd 100644 --- a/packages/layers/src/image/shaders/image_vert.glsl +++ b/packages/layers/src/image/shaders/image_vert.glsl @@ -1,5 +1,6 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 14) in vec2 a_Uv; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_POSITION_64LOW) in vec2 a_Position64Low; +layout(location = ATTRIBUTE_LOCATION_UV) in vec2 a_Uv; layout(std140) uniform commonUniforms { float u_opacity:1.0; @@ -11,9 +12,9 @@ layout(std140) uniform commonUniforms { out vec2 v_texCoord; #pragma include "projection" + void main() { - v_texCoord = a_Uv; - vec4 project_pos = project_position(vec4(a_Position, 1.0)); - gl_Position = project_common_position_to_clipspace_v2(vec4(project_pos.xy,0., 1.0)); - + v_texCoord = a_Uv; + vec4 project_pos = project_position(vec4(a_Position, 1.0), a_Position64Low); + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy, 0.0, 1.0)); } diff --git a/packages/layers/src/line/models/arc.ts b/packages/layers/src/line/models/arc.ts index b6d4c60d9ea..5dd07e127a4 100644 --- a/packages/layers/src/line/models/arc.ts +++ b/packages/layers/src/line/models/arc.ts @@ -6,9 +6,8 @@ import type { ITexture2D, } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; -import { rgb2arr } from '@antv/l7-utils'; +import { fp64LowPart, rgb2arr } from '@antv/l7-utils'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import type { ILineLayerStyleOptions } from '../../core/interface'; import { LineArcTriangulation } from '../../core/triangulation'; import arc_line_frag from '../shaders/arc/line_arc_frag.glsl'; @@ -19,6 +18,16 @@ const lineStyleObj: { [key: string]: number } = { dash: 1.0, }; export default class ArcModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + SIZE: 9, + INSTANCE: 10, + INSTANCE_64LOW: 11, + UV: 12, + THETA_OFFSET: 13, + }); + } protected texture: ITexture2D; protected getCommonUniformsInfo(): { uniformsArray: number[]; @@ -120,6 +129,7 @@ export default class ArcModel extends BaseModel { moduleName: 'lineArc2d' + type, vertexShader: vert, fragmentShader: frag, + defines: this.getDefines(), inject: this.getInject(), triangulation: LineArcTriangulation, depth: { enable: false }, @@ -134,7 +144,7 @@ export default class ArcModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Size', - shaderLocation: ShaderLocation.SIZE, + shaderLocation: this.attributeLocation.SIZE, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, @@ -149,12 +159,13 @@ export default class ArcModel extends BaseModel { }, }); + // 弧线起始点信息 this.styleAttributeService.registerStyleAttribute({ - name: 'instance', // 弧线起始点信息 + name: 'instance', type: AttributeType.Attribute, descriptor: { name: 'a_Instance', - shaderLocation: 12, + shaderLocation: this.attributeLocation.INSTANCE, buffer: { usage: gl.STATIC_DRAW, data: [], @@ -167,14 +178,37 @@ export default class ArcModel extends BaseModel { }, }); + // save low part for enabled double precision INSTANCE attribute + this.styleAttributeService.registerStyleAttribute({ + name: 'instance64Low', + type: AttributeType.Attribute, + descriptor: { + name: 'a_Instance64Low', + shaderLocation: this.attributeLocation.INSTANCE_64LOW, + buffer: { + usage: gl.STATIC_DRAW, + data: [], + type: gl.FLOAT, + }, + size: 4, + update: (feature: IEncodeFeature, featureIdx: number, vertex: number[]) => { + return [ + fp64LowPart(vertex[3]), + fp64LowPart(vertex[4]), + fp64LowPart(vertex[5]), + fp64LowPart(vertex[6]), + ]; + }, + }, + }); + this.styleAttributeService.registerStyleAttribute({ name: 'uv', type: AttributeType.Attribute, descriptor: { name: 'a_iconMapUV', - shaderLocation: 14, + shaderLocation: this.attributeLocation.UV, buffer: { - // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, data: [], type: gl.FLOAT, @@ -188,6 +222,25 @@ export default class ArcModel extends BaseModel { }, }, }); + + this.styleAttributeService.registerStyleAttribute({ + name: 'thetaOffset', + type: AttributeType.Attribute, + descriptor: { + name: 'a_ThetaOffset', + shaderLocation: this.attributeLocation.THETA_OFFSET, + buffer: { + usage: gl.STATIC_DRAW, + data: [], + type: gl.FLOAT, + }, + size: 1, + update: (feature: IEncodeFeature) => { + const { thetaOffset: op = 1 } = feature; + return [op]; + }, + }, + }); } private updateTexture = () => { diff --git a/packages/layers/src/line/models/arc_3d.ts b/packages/layers/src/line/models/arc_3d.ts index 8d9547bbd78..11145b879f4 100644 --- a/packages/layers/src/line/models/arc_3d.ts +++ b/packages/layers/src/line/models/arc_3d.ts @@ -6,13 +6,12 @@ import type { ITexture2D, } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; -import { rgb2arr } from '@antv/l7-utils'; +import { fp64LowPart, rgb2arr } from '@antv/l7-utils'; import BaseModel from '../../core/BaseModel'; import type { ILineLayerStyleOptions } from '../../core/interface'; import { LineArcTriangulation } from '../../core/triangulation'; import { EARTH_RADIUS } from '../../earth/utils'; // arc3d line layer -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import arc3d_line_frag from '../shaders/arc3d/line_arc_3d_frag.glsl'; import arc3d_line_vert from '../shaders/arc3d/line_arc_3d_vert.glsl'; @@ -21,6 +20,16 @@ const lineStyleObj: { [key: string]: number } = { dash: 1.0, }; export default class Arc3DModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + SIZE: 9, + INSTANCE: 10, + INSTANCE_64LOW: 11, + UV: 12, + THETA_OFFSET: 13, + }); + } protected texture: ITexture2D; // public enableShaderEncodeStyles = ['opacity']; protected getCommonUniformsInfo(): { @@ -117,6 +126,7 @@ export default class Arc3DModel extends BaseModel { moduleName: 'lineArc3d' + type, vertexShader: vert, fragmentShader: frag, + defines: this.getDefines(), inject: this.getInject(), triangulation: LineArcTriangulation, styleOption: { segmentNumber }, @@ -129,9 +139,8 @@ export default class Arc3DModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Size', - shaderLocation: ShaderLocation.SIZE, + shaderLocation: this.attributeLocation.SIZE, buffer: { - // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, data: [], type: gl.FLOAT, @@ -149,7 +158,7 @@ export default class Arc3DModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Instance', - shaderLocation: 12, + shaderLocation: this.attributeLocation.INSTANCE, buffer: { usage: gl.STATIC_DRAW, data: [], @@ -162,12 +171,36 @@ export default class Arc3DModel extends BaseModel { }, }); + // save low part for enabled double precision INSTANCE attribute + this.styleAttributeService.registerStyleAttribute({ + name: 'instance64Low', + type: AttributeType.Attribute, + descriptor: { + name: 'a_Instance64Low', + shaderLocation: this.attributeLocation.INSTANCE_64LOW, + buffer: { + usage: gl.STATIC_DRAW, + data: [], + type: gl.FLOAT, + }, + size: 4, + update: (feature: IEncodeFeature, featureIdx: number, vertex: number[]) => { + return [ + fp64LowPart(vertex[3]), + fp64LowPart(vertex[4]), + fp64LowPart(vertex[5]), + fp64LowPart(vertex[6]), + ]; + }, + }, + }); + this.styleAttributeService.registerStyleAttribute({ name: 'uv', type: AttributeType.Attribute, descriptor: { name: 'a_iconMapUV', - shaderLocation: 14, + shaderLocation: this.attributeLocation.UV, buffer: { usage: gl.DYNAMIC_DRAW, data: [], @@ -182,6 +215,25 @@ export default class Arc3DModel extends BaseModel { }, }, }); + + this.styleAttributeService.registerStyleAttribute({ + name: 'thetaOffset', + type: AttributeType.Attribute, + descriptor: { + name: 'a_ThetaOffset', + shaderLocation: this.attributeLocation.THETA_OFFSET, + buffer: { + usage: gl.STATIC_DRAW, + data: [], + type: gl.FLOAT, + }, + size: 1, + update: (feature: IEncodeFeature) => { + const { thetaOffset: op = 1 } = feature; + return [op]; + }, + }, + }); } private updateTexture = () => { diff --git a/packages/layers/src/line/models/flow.ts b/packages/layers/src/line/models/flow.ts index 65e12c121d6..da0134e2b46 100644 --- a/packages/layers/src/line/models/flow.ts +++ b/packages/layers/src/line/models/flow.ts @@ -1,15 +1,22 @@ import type { IEncodeFeature, IModel } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; +import { fp64LowPart } from '@antv/l7-utils'; import BaseModel from '../../core/BaseModel'; import type { IFlowLineStyleOptions } from '../../core/interface'; import { FlowLineTriangulation } from '../../core/line_trangluation'; import flow_line_frag from '../shaders/flow/flow_line_frag.glsl'; - -// linear simple line shader - -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import flow_line_vert from '../shaders/flow/flow_line_vert.glsl'; + export default class FlowLineModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + SIZE: 9, + INSTANCE: 10, + INSTANCE_64LOW: 11, + NORMAL: 12, + }); + } protected getCommonUniformsInfo(): { uniformsArray: number[]; uniformsLength: number; @@ -40,6 +47,7 @@ export default class FlowLineModel extends BaseModel { moduleName: 'flow_line', vertexShader: flow_line_vert, fragmentShader: flow_line_frag, + defines: this.getDefines(), inject: this.getInject(), triangulation: FlowLineTriangulation, styleOption: (this.layer.getLayerConfig() as IFlowLineStyleOptions).symbol, @@ -56,7 +64,7 @@ export default class FlowLineModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Size', // 宽度 - shaderLocation: ShaderLocation.SIZE, + shaderLocation: this.attributeLocation.SIZE, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, @@ -70,12 +78,13 @@ export default class FlowLineModel extends BaseModel { }, }, }); + this.styleAttributeService.registerStyleAttribute({ name: 'instance', // 弧线起始点信息 type: AttributeType.Attribute, descriptor: { name: 'a_Instance', - shaderLocation: 12, + shaderLocation: this.attributeLocation.INSTANCE, buffer: { usage: gl.STATIC_DRAW, data: [], @@ -88,14 +97,37 @@ export default class FlowLineModel extends BaseModel { }, }); + // save low part for enabled double precision INSTANCE attribute + this.styleAttributeService.registerStyleAttribute({ + name: 'instance64Low', + type: AttributeType.Attribute, + descriptor: { + name: 'a_Instance64Low', + shaderLocation: this.attributeLocation.INSTANCE_64LOW, + buffer: { + usage: gl.STATIC_DRAW, + data: [], + type: gl.FLOAT, + }, + size: 4, + update: (feature: IEncodeFeature, featureIdx: number, vertex: number[]) => { + return [ + fp64LowPart(vertex[3]), + fp64LowPart(vertex[4]), + fp64LowPart(vertex[5]), + fp64LowPart(vertex[6]), + ]; + }, + }, + }); + this.styleAttributeService.registerStyleAttribute({ name: 'normal', type: AttributeType.Attribute, descriptor: { name: 'a_Normal', - shaderLocation: ShaderLocation.NORMAL, + shaderLocation: this.attributeLocation.NORMAL, buffer: { - // give the WebGL driver a hint that this buffer may change usage: gl.STATIC_DRAW, data: [], type: gl.FLOAT, diff --git a/packages/layers/src/line/models/great_circle.ts b/packages/layers/src/line/models/great_circle.ts index 4b8c7824920..6ba7ceec769 100644 --- a/packages/layers/src/line/models/great_circle.ts +++ b/packages/layers/src/line/models/great_circle.ts @@ -6,9 +6,8 @@ import type { ITexture2D, } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; -import { rgb2arr } from '@antv/l7-utils'; +import { fp64LowPart, rgb2arr } from '@antv/l7-utils'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import type { ILineLayerStyleOptions } from '../../core/interface'; import { LineArcTriangulation } from '../../core/triangulation'; import line_arc_frag from '../shaders/greatCircle/line_arc_great_circle_frag.glsl'; @@ -19,6 +18,15 @@ const lineStyleObj: { [key: string]: number } = { }; export default class GreatCircleModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + SIZE: 9, + INSTANCE: 10, + INSTANCE_64LOW: 11, + UV: 12, + }); + } protected texture: ITexture2D; protected getCommonUniformsInfo(): { uniformsArray: number[]; @@ -107,6 +115,7 @@ export default class GreatCircleModel extends BaseModel { fragmentShader: line_arc_frag, triangulation: LineArcTriangulation, styleOption: { segmentNumber }, + defines: this.getDefines(), inject: this.getInject(), depth: { enable: false }, }); @@ -118,7 +127,7 @@ export default class GreatCircleModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Size', - shaderLocation: ShaderLocation.SIZE, + shaderLocation: this.attributeLocation.SIZE, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, @@ -138,7 +147,7 @@ export default class GreatCircleModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Instance', - shaderLocation: 12, + shaderLocation: this.attributeLocation.INSTANCE, buffer: { usage: gl.STATIC_DRAW, data: [], @@ -151,12 +160,36 @@ export default class GreatCircleModel extends BaseModel { }, }); + // save low part for enabled double precision INSTANCE attribute + this.styleAttributeService.registerStyleAttribute({ + name: 'instance64Low', + type: AttributeType.Attribute, + descriptor: { + name: 'a_Instance64Low', + shaderLocation: this.attributeLocation.INSTANCE_64LOW, + buffer: { + usage: gl.STATIC_DRAW, + data: [], + type: gl.FLOAT, + }, + size: 4, + update: (feature: IEncodeFeature, featureIdx: number, vertex: number[]) => { + return [ + fp64LowPart(vertex[3]), + fp64LowPart(vertex[4]), + fp64LowPart(vertex[5]), + fp64LowPart(vertex[6]), + ]; + }, + }, + }); + this.styleAttributeService.registerStyleAttribute({ name: 'uv', type: AttributeType.Attribute, descriptor: { name: 'a_iconMapUV', - shaderLocation: 14, + shaderLocation: this.attributeLocation.UV, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, diff --git a/packages/layers/src/line/models/line.ts b/packages/layers/src/line/models/line.ts index 4e107fb87a9..d70db29c773 100644 --- a/packages/layers/src/line/models/line.ts +++ b/packages/layers/src/line/models/line.ts @@ -12,11 +12,20 @@ import type { ILineLayerStyleOptions } from '../../core/interface'; import { LinearDir, TextureBlend } from '../../core/interface'; import { LineTriangulation } from '../../core/triangulation'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import line_frag from '../shaders/line/line_frag.glsl'; import line_vert from '../shaders/line/line_vert.glsl'; export default class LineModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + SIZE: 9, + DISTANCE_INDEX: 10, + NORMAL: 11, + UV: 12, + }); + } + private textureEventFlag: boolean = false; protected texture: ITexture2D = this.createTexture2D({ data: new Uint8Array([0, 0, 0, 0]), @@ -121,6 +130,7 @@ export default class LineModel extends BaseModel { vertexShader: vert, fragmentShader: frag, triangulation: LineTriangulation, + defines: this.getDefines(), inject: this.getInject(), depth: { enable: depth }, }); @@ -138,13 +148,17 @@ export default class LineModel extends BaseModel { type: '', }; } + protected registerBuiltinAttributes() { + // 注册 Position 属性 64 位地位部分,经纬度数据开启双精度,避免大于 20层级以上出现数据偏移 + this.registerPosition64LowAttribute(); + this.styleAttributeService.registerStyleAttribute({ name: 'distanceAndIndex', type: AttributeType.Attribute, descriptor: { name: 'a_DistanceAndIndexAndMiter', - shaderLocation: 10, + shaderLocation: this.attributeLocation.DISTANCE_INDEX, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.STATIC_DRAW, @@ -172,7 +186,7 @@ export default class LineModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Size', - shaderLocation: ShaderLocation.SIZE, + shaderLocation: this.attributeLocation.SIZE, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, @@ -187,13 +201,12 @@ export default class LineModel extends BaseModel { }, }); - // point layer size; this.styleAttributeService.registerStyleAttribute({ name: 'normal_total_distance', type: AttributeType.Attribute, descriptor: { name: 'a_Normal_Total_Distance', - shaderLocation: ShaderLocation.NORMAL, + shaderLocation: this.attributeLocation.NORMAL, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.STATIC_DRAW, @@ -218,7 +231,7 @@ export default class LineModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_iconMapUV', - shaderLocation: ShaderLocation.UV, + shaderLocation: this.attributeLocation.UV, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, diff --git a/packages/layers/src/line/models/simple_line.ts b/packages/layers/src/line/models/simple_line.ts index 10e174458f5..415604a3308 100644 --- a/packages/layers/src/line/models/simple_line.ts +++ b/packages/layers/src/line/models/simple_line.ts @@ -2,12 +2,18 @@ import type { IEncodeFeature, IModel } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; import { rgb2arr } from '@antv/l7-utils'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import type { ILineLayerStyleOptions } from '../../core/interface'; import { SimpleLineTriangulation } from '../../core/triangulation'; import simple_line_frag from '../shaders/simple/simpleline_frag.glsl'; import simple_line_vert from '../shaders/simple/simpleline_vert.glsl'; + export default class SimpleLineModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + SIZE: 9, + }); + } protected getCommonUniformsInfo(): { uniformsArray: number[]; uniformsLength: number; @@ -70,6 +76,7 @@ export default class SimpleLineModel extends BaseModel { vertexShader: vert, fragmentShader: frag, triangulation: SimpleLineTriangulation, + defines: this.getDefines(), inject: this.getInject(), primitive: gl.LINES, depth: { enable: false }, @@ -79,57 +86,16 @@ export default class SimpleLineModel extends BaseModel { return [model]; } protected registerBuiltinAttributes() { - // this.styleAttributeService.registerStyleAttribute({ - // name: 'distance', - // type: AttributeType.Attribute, - // descriptor: { - // name: 'a_Distance', - // shaderLocation: 14, - // buffer: { - // // give the WebGL driver a hint that this buffer may change - // usage: gl.STATIC_DRAW, - // data: [], - // type: gl.FLOAT, - // }, - // size: 1, - // update: ( - // feature: IEncodeFeature, - // featureIdx: number, - // vertex: number[], - // ) => { - // return [vertex[3]]; - // }, - // }, - // }); - // this.styleAttributeService.registerStyleAttribute({ - // name: 'total_distance', - // type: AttributeType.Attribute, - // descriptor: { - // name: 'a_Total_Distance', - // shaderLocation: 13,//枚举不够了,先固定写值吧,在shader中location也成一致的并且不与其他的重复就行了 - // buffer: { - // // give the WebGL driver a hint that this buffer may change - // usage: gl.STATIC_DRAW, - // data: [], - // type: gl.FLOAT, - // }, - // size: 1, - // update: ( - // feature: IEncodeFeature, - // featureIdx: number, - // vertex: number[], - // ) => { - // return [vertex[5]]; - // }, - // }, - // }); + // 注册 Position 属性 64 位地位部分,经纬度数据开启双精度,避免大于 20层级以上出现数据偏移 + this.registerPosition64LowAttribute(); + //size.x,size,y,distance,totalDistance this.styleAttributeService.registerStyleAttribute({ name: 'sizeDistanceAndTotalDistance', type: AttributeType.Attribute, descriptor: { name: 'a_SizeDistanceAndTotalDistance', - shaderLocation: ShaderLocation.SIZE, + shaderLocation: this.attributeLocation.SIZE, buffer: { usage: gl.STATIC_DRAW, data: [], diff --git a/packages/layers/src/line/models/wall.ts b/packages/layers/src/line/models/wall.ts index f2c72c08043..c63173add01 100644 --- a/packages/layers/src/line/models/wall.ts +++ b/packages/layers/src/line/models/wall.ts @@ -8,12 +8,20 @@ import type { import { AttributeType, gl } from '@antv/l7-core'; import { rgb2arr } from '@antv/l7-utils'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import type { ILineLayerStyleOptions } from '../../core/interface'; import { LineTriangulation } from '../../core/triangulation'; import line_frag from '../shaders/wall/wall_frag.glsl'; import line_vert from '../shaders/wall/wall_vert.glsl'; export default class LineWallModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + SIZE: 9, + NORMAL: 12, + UV: 13, + DISTANCE_MITER_TOTAL: 15, + }); + } protected texture: ITexture2D; protected getCommonUniformsInfo(): { uniformsArray: number[]; @@ -89,6 +97,7 @@ export default class LineWallModel extends BaseModel { vertexShader: line_vert, fragmentShader: line_frag, triangulation: LineTriangulation, + defines: this.getDefines(), inject: this.getInject(), depth: { enable: false }, blend: this.getBlend(), @@ -96,49 +105,15 @@ export default class LineWallModel extends BaseModel { return [model]; } protected registerBuiltinAttributes() { - this.styleAttributeService.registerStyleAttribute({ - name: 'distance', - type: AttributeType.Attribute, - descriptor: { - name: 'a_Distance', - shaderLocation: 15, - buffer: { - // give the WebGL driver a hint that this buffer may change - usage: gl.STATIC_DRAW, - data: [], - type: gl.FLOAT, - }, - size: 1, - update: (feature: IEncodeFeature, featureIdx: number, vertex: number[]) => { - return [vertex[3]]; - }, - }, - }); - this.styleAttributeService.registerStyleAttribute({ - name: 'total_distance', - type: AttributeType.Attribute, - descriptor: { - name: 'a_Total_Distance', - shaderLocation: 11, - buffer: { - // give the WebGL driver a hint that this buffer may change - usage: gl.STATIC_DRAW, - data: [], - type: gl.FLOAT, - }, - size: 1, - update: (feature: IEncodeFeature, featureIdx: number, vertex: number[]) => { - return [vertex[5]]; - }, - }, - }); + // 注册 Position 属性 64 位地位部分,经纬度数据开启双精度,避免大于 20层级以上出现数据偏移 + this.registerPosition64LowAttribute(); this.styleAttributeService.registerStyleAttribute({ name: 'size', type: AttributeType.Attribute, descriptor: { name: 'a_Size', - shaderLocation: ShaderLocation.SIZE, + shaderLocation: this.attributeLocation.SIZE, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, @@ -153,13 +128,12 @@ export default class LineWallModel extends BaseModel { }, }); - // point layer size; this.styleAttributeService.registerStyleAttribute({ name: 'normal', type: AttributeType.Attribute, descriptor: { name: 'a_Normal', - shaderLocation: ShaderLocation.NORMAL, + shaderLocation: this.attributeLocation.NORMAL, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.STATIC_DRAW, @@ -181,20 +155,21 @@ export default class LineWallModel extends BaseModel { }); this.styleAttributeService.registerStyleAttribute({ - name: 'miter', + name: 'distanceAndTotalAndMiter', type: AttributeType.Attribute, descriptor: { - name: 'a_Miter', - shaderLocation: 10, + name: 'a_Distance_Total_Miter', + shaderLocation: this.attributeLocation.DISTANCE_MITER_TOTAL, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.STATIC_DRAW, data: [], type: gl.FLOAT, }, - size: 1, + size: 3, update: (feature: IEncodeFeature, featureIdx: number, vertex: number[]) => { - return [vertex[4]]; + // [distance, miter, total_distance] + return [vertex[3], vertex[4], vertex[5]]; }, }, }); @@ -204,7 +179,7 @@ export default class LineWallModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_iconMapUV', - shaderLocation: 14, + shaderLocation: this.attributeLocation.UV, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, diff --git a/packages/layers/src/line/shaders/arc/line_arc_vert.glsl b/packages/layers/src/line/shaders/arc/line_arc_vert.glsl index 3fb503ee43e..b8e33559226 100644 --- a/packages/layers/src/line/shaders/arc/line_arc_vert.glsl +++ b/packages/layers/src/line/shaders/arc/line_arc_vert.glsl @@ -1,10 +1,12 @@ -#define Animate 0.0 -#define LineTexture 1.0 -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in float a_Size; -layout(location = 12) in vec4 a_Instance; -layout(location = 14) in vec2 a_iconMapUV; +#define Animate (0.0) +#define LineTexture (1.0) + +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in float a_Size; +layout(location = ATTRIBUTE_LOCATION_INSTANCE) in vec4 a_Instance; +layout(location = ATTRIBUTE_LOCATION_INSTANCE_64LOW) in vec4 a_Instance64Low; +layout(location = ATTRIBUTE_LOCATION_UV) in vec2 a_iconMapUV; layout(std140) uniform commonUniorm { vec4 u_animate: [ 1., 2., 1.0, 0.2 ]; @@ -22,6 +24,7 @@ layout(std140) uniform commonUniorm { float u_time; float u_linearColor: 0.0; }; + out vec4 v_color; out vec2 v_iconMapUV; out vec4 v_lineData; @@ -29,13 +32,12 @@ out vec4 v_lineData; out vec4 v_dash_array; out float v_distance_ratio; - #pragma include "projection" #pragma include "project" #pragma include "picking" float bezier3(vec3 arr, float t) { - float ut = 1. - t; + float ut = 1.0 - t; return (arr.x * ut + arr.y * t) * ut + (arr.y * ut + arr.z * t) * t; } vec2 midPoint(vec2 source, vec2 target, float arcThetaOffset) { @@ -45,10 +47,12 @@ vec2 midPoint(vec2 source, vec2 target, float arcThetaOffset) { float thetaOffset = arcThetaOffset; float r2 = r / 2.0 / cos(thetaOffset); float theta2 = theta + thetaOffset; - vec2 mid = vec2(r2*cos(theta2) + source.x, r2*sin(theta2) + source.y); - if(u_lineDir == 1.0) { // 正向 + vec2 mid = vec2(r2 * cos(theta2) + source.x, r2 * sin(theta2) + source.y); + if (u_lineDir == 1.0) { + // 正向 return mid; - } else { // 逆向 + } else { + // 逆向 // (mid + vmin)/2 = (s + t)/2 vec2 vmid = source + target - mid; return vmid; @@ -56,23 +60,23 @@ vec2 midPoint(vec2 source, vec2 target, float arcThetaOffset) { // return mid; } float getSegmentRatio(float index) { - // dash: index / (segmentNumber - 1.); - // normal: smoothstep(0.0, 1.0, index / (segmentNumber - 1.)); - return smoothstep(0.0, 1.0, index / (segmentNumber - 1.)); - // return index / (segmentNumber - 1.); + // dash: index / (segmentNumber - 1.); + // normal: smoothstep(0.0, 1.0, index / (segmentNumber - 1.)); + return smoothstep(0.0, 1.0, index / (segmentNumber - 1.0)); + // return index / (segmentNumber - 1.); } -vec2 interpolate (vec2 source, vec2 target, float t, float arcThetaOffset) { +vec2 interpolate(vec2 source, vec2 target, float t, float arcThetaOffset) { // if the angularDist is PI, linear interpolation is applied. otherwise, use spherical interpolation vec2 mid = midPoint(source, target, arcThetaOffset); vec3 x = vec3(source.x, mid.x, target.x); vec3 y = vec3(source.y, mid.y, target.y); - return vec2(bezier3(x ,t), bezier3(y,t)); + return vec2(bezier3(x, t), bezier3(y, t)); } vec2 getExtrusionOffset(vec2 line_clipspace, float offset_direction) { // normalized direction of the line vec2 dir_screenspace = normalize(line_clipspace); // rotate by 90 degrees - dir_screenspace = vec2(-dir_screenspace.y, dir_screenspace.x); + dir_screenspace = vec2(-dir_screenspace.y, dir_screenspace.x); vec2 offset = dir_screenspace * offset_direction * setPickingSize(a_Size) / 2.0; return offset; } @@ -81,43 +85,34 @@ vec2 getNormal(vec2 line_clipspace, float offset_direction) { vec2 dir_screenspace = normalize(line_clipspace); // rotate by 90 degrees dir_screenspace = vec2(-dir_screenspace.y, dir_screenspace.x); - return reverse_offset_normal(vec3(dir_screenspace,1.0)).xy * sign(offset_direction); + return dir_screenspace.xy * sign(offset_direction); } void main() { //vs中计算渐变色 - if(u_linearColor==1.0){ + if (u_linearColor == 1.0) { float d_segmentIndex = a_Position.x + 1.0; // 当前顶点在弧线中所处的分段位置 - v_color = mix(u_sourceColor, u_targetColor, d_segmentIndex/segmentNumber); - } - else{ + v_color = mix(u_sourceColor, u_targetColor, d_segmentIndex / segmentNumber); + } else { v_color = a_Color; } v_color.a = v_color.a * opacity; - vec2 source = a_Instance.rg; // 起始点 - vec2 target = a_Instance.ba; // 终点 - - + vec2 source_world = a_Instance.rg; // 起始点 + vec2 target_world = a_Instance.ba; // 终点 float segmentIndex = a_Position.x; float segmentRatio = getSegmentRatio(segmentIndex); - //计算dashArray和distanceRatio 输出到片元 - vec2 s = source; - vec2 t = target; - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x - s = unProjCustomCoord(source); - t = unProjCustomCoord(target); - } - float total_Distance = pixelDistance(s, t) / 2.0 * PI; + // 计算 dashArray 和 distanceRatio 输出到片元 + float total_Distance = pixelDistance(source_world, target_world) / 2.0 * PI; v_dash_array = pow(2.0, 20.0 - u_Zoom) * u_dash_array / total_Distance; v_distance_ratio = segmentIndex / segmentNumber; float indexDir = mix(-1.0, 1.0, step(segmentIndex, 0.0)); float nextSegmentRatio = getSegmentRatio(segmentIndex + indexDir); float d_distance_ratio; - + if(u_animate.x == Animate) { d_distance_ratio = segmentIndex / segmentNumber; if(u_lineDir != 1.0) { @@ -127,38 +122,35 @@ void main() { v_lineData.b = d_distance_ratio; - vec4 curr = project_position(vec4(interpolate(source, target, segmentRatio, thetaOffset), 0.0, 1.0)); - vec4 next = project_position(vec4(interpolate(source, target, nextSegmentRatio, thetaOffset), 0.0, 1.0)); + vec4 source = project_position(vec4(source_world, 0, 1.), a_Instance64Low.xy); + vec4 target = project_position(vec4(target_world, 0, 1.), a_Instance64Low.zw); - - vec2 offset = project_pixel(getExtrusionOffset((next.xy - curr.xy) * indexDir, a_Position.y)); + vec2 currPos = interpolate(source.xy, target.xy, segmentRatio, thetaOffset); + vec2 nextPos = interpolate(source.xy, target.xy, nextSegmentRatio, thetaOffset); + vec2 offset = project_pixel( + getExtrusionOffset((nextPos.xy - currPos.xy) * indexDir, a_Position.y) + ); float d_segmentIndex = a_Position.x + 1.0; // 当前顶点在弧线中所处的分段位置 v_lineData.r = d_segmentIndex; if(LineTexture == u_line_texture) { // 开启贴图模式 - float arcDistrance = length(source - target); // 起始点和终点的距离 - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20) { // amap - arcDistrance *= 1000000.0; - } - if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { // mapbox - // arcDistrance *= 8.0; - arcDistrance = project_pixel_allmap(arcDistrance); - } + arcDistrance = project_pixel(arcDistrance); + v_iconMapUV = a_iconMapUV; float pixelLen = project_pixel_texture(u_icon_step); // 贴图沿弧线方向的长度 - 随地图缩放改变 - float texCount = floor(arcDistrance/pixelLen); // 贴图在弧线上重复的数量 + float texCount = floor(arcDistrance / pixelLen); // 贴图在弧线上重复的数量 v_lineData.g = texCount; float lineOffsetWidth = length(offset + offset * sign(a_Position.y)); // 线横向偏移的距离 float linePixelSize = project_pixel(a_Size); // 定点位置偏移 - v_lineData.a = lineOffsetWidth/linePixelSize; // 线图层贴图部分的 v 坐标值 + v_lineData.a = lineOffsetWidth / linePixelSize; // 线图层贴图部分的 v 坐标值 } - gl_Position = project_common_position_to_clipspace_v2(vec4(curr.xy + offset, 0, 1.0)); + gl_Position = project_common_position_to_clipspace(vec4(currPos.xy + offset, 0, 1.0)); setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/line/shaders/arc3d/line_arc_3d_frag.glsl b/packages/layers/src/line/shaders/arc3d/line_arc_3d_frag.glsl index 5f8e12d47b4..7efbf3d107c 100644 --- a/packages/layers/src/line/shaders/arc3d/line_arc_3d_frag.glsl +++ b/packages/layers/src/line/shaders/arc3d/line_arc_3d_frag.glsl @@ -23,12 +23,11 @@ layout(std140) uniform commonUniorm { float u_linearColor: 0.0; }; -// varying vec2 v_normal; -in vec4 v_dash_array; in vec4 v_color; -in vec4 v_line_data; +in vec4 v_dash_array; in float v_segmentIndex; in vec2 v_iconMapUV; +in vec4 v_line_data; out vec4 outputColor; @@ -57,7 +56,7 @@ void main() { alpha = clamp(alpha, 0.0, 1.0); outputColor.a *= alpha; - // u_animate + // u_animate // x enable // y duration // z interval diff --git a/packages/layers/src/line/shaders/arc3d/line_arc_3d_vert.glsl b/packages/layers/src/line/shaders/arc3d/line_arc_3d_vert.glsl index 045397d18c1..d3d56babbda 100644 --- a/packages/layers/src/line/shaders/arc3d/line_arc_3d_vert.glsl +++ b/packages/layers/src/line/shaders/arc3d/line_arc_3d_vert.glsl @@ -2,11 +2,13 @@ #define LineTypeDash 1.0 #define Animate 0.0 #define LineTexture 1.0 -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in float a_Size; -layout(location = 12) in vec4 a_Instance; -layout(location = 14) in vec2 a_iconMapUV; + +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in float a_Size; +layout(location = ATTRIBUTE_LOCATION_INSTANCE) in vec4 a_Instance; +layout(location = ATTRIBUTE_LOCATION_INSTANCE_64LOW) in vec4 a_Instance64Low; +layout(location = ATTRIBUTE_LOCATION_UV) in vec2 a_iconMapUV; layout(std140) uniform commonUniorm { @@ -75,7 +77,7 @@ vec2 getNormal(vec2 line_clipspace, float offset_direction) { vec2 dir_screenspace = normalize(line_clipspace); // rotate by 90 degrees dir_screenspace = vec2(-dir_screenspace.y, dir_screenspace.x); - return reverse_offset_normal(vec3(dir_screenspace,1.0)).xy * sign(offset_direction); + return dir_screenspace.xy * sign(offset_direction); } float torad(float deg) { @@ -107,8 +109,8 @@ void main() { v_color = a_Color; } v_color.a = v_color.a * opacity; - vec2 source = project_position(vec4(a_Instance.rg, 0, 0)).xy; - vec2 target = project_position(vec4(a_Instance.ba, 0, 0)).xy; + vec2 source = project_position(vec4(a_Instance.rg, 0, 0), a_Instance64Low.xy).xy; + vec2 target = project_position(vec4(a_Instance.ba, 0, 0), a_Instance64Low.zw).xy; float segmentIndex = a_Position.x; float segmentRatio = getSegmentRatio(segmentIndex); float indexDir = mix(-1.0, 1.0, step(segmentIndex, 0.0)); @@ -116,14 +118,7 @@ void main() { float d_distance_ratio; if(u_line_type == LineTypeDash) { d_distance_ratio = segmentIndex / segmentNumber; - vec2 s = source; - vec2 t = target; - - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x - s = unProjCustomCoord(source); - t = unProjCustomCoord(target); - } - float total_Distance = pixelDistance(s, t) / 2.0 * PI; + float total_Distance = pixelDistance(source, target) / 2.0 * PI; v_dash_array = pow(2.0, 20.0 - u_Zoom) * u_dash_array / (total_Distance / segmentNumber * segmentIndex); } if(u_animate.x == Animate) { @@ -139,7 +134,7 @@ void main() { v_segmentIndex = a_Position.x; - if(LineTexture == u_line_texture && u_line_type != LineTypeDash) { // 开启贴图模式 + if(LineTexture == u_line_texture && u_line_type != LineTypeDash) { // 开启贴图模式 float arcDistrance = length(source - target); float pixelLen = project_pixel_texture(u_icon_step); @@ -154,7 +149,7 @@ void main() { } - gl_Position = project_common_position_to_clipspace_v2(vec4(curr.xy + project_pixel(offset), curr.z * thetaOffset, 1.0)); + gl_Position = project_common_position_to_clipspace(vec4(curr.xy + project_pixel(offset), curr.z * thetaOffset, 1.0)); // 地球模式 if(u_globel > 0.0) { @@ -173,10 +168,10 @@ void main() { float lineHeight = u_global_height * (-4.0*segmentRatio*segmentRatio + 4.0 * segmentRatio) * lnglatLength; // 地球点位 vec3 globalPoint = normalize(mix(startLngLat, endLngLat, segmentRatio)) * (globalRadius + lineHeight) + lnglatOffset * a_Size; - + gl_Position = u_ViewProjectionMatrix * vec4(globalPoint, 1.0); } - + setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/line/shaders/flow/flow_line_vert.glsl b/packages/layers/src/line/shaders/flow/flow_line_vert.glsl index 705205c9232..5c88ccde5ac 100644 --- a/packages/layers/src/line/shaders/flow/flow_line_vert.glsl +++ b/packages/layers/src/line/shaders/flow/flow_line_vert.glsl @@ -1,8 +1,9 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in vec2 a_Size; -layout(location = 12) in vec4 a_Instance; -layout(location = 13) in vec3 a_Normal; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in vec2 a_Size; +layout(location = ATTRIBUTE_LOCATION_INSTANCE) in vec4 a_Instance; +layout(location = ATTRIBUTE_LOCATION_INSTANCE_64LOW) in vec4 a_Instance64Low; +layout(location = ATTRIBUTE_LOCATION_NORMAL) in vec3 a_Normal; layout(std140) uniform commonUniorm { float u_gap_width: 1.0; @@ -17,78 +18,59 @@ layout(std140) uniform commonUniorm { out vec4 v_color; vec2 project_pixel_offset(vec2 offsets) { + vec2 data = project_pixel(offsets); - vec2 data = project_pixel(offsets); - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { - // P20_2 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减3 - return data; - } - - return vec2(data.x, -data.y);; + return vec2(data.x, -data.y); } vec2 line_dir(vec2 target, vec2 source) { - - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { - // P20_2 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减3 - return normalize(target - source); - } return normalize(ProjectFlat(target) - ProjectFlat(source)); } -float flag_gap() { - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { - // P20_2 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减3 - return 1.; - } - return -1.; - -} - void main() { + // 透明度计算 + vec2 source_world = a_Instance.rg; // 起点 + vec2 target_world = a_Instance.ba; // 终点 + vec2 flowlineDir = line_dir(target_world, source_world); + vec2 perpendicularDir = vec2(-flowlineDir.y, flowlineDir.x); -// 透明度计算 - vec2 source = a_Instance.rg; // 起始点 - vec2 target = a_Instance.ba; // 终点 - vec2 flowlineDir = line_dir(target,source); - vec2 perpendicularDir = vec2(-flowlineDir.y, flowlineDir.x); // mapbox || 高德 - - vec2 position = mix(source, target, a_Position.x); - - float lengthCommon = length(project_position(vec4(target,0,1)) - project_position(vec4(source,0,1))); // + vec2 position = mix(source_world, target_world, a_Position.x); + vec2 position64Low = mix(a_Instance64Low.rg, a_Instance64Low.ba, a_Position.x); + + float lengthCommon = length( + project_position(vec4(target_world, 0, 1)) - project_position(vec4(source_world, 0, 1)) + ); vec2 offsetDistances = a_Size.x * project_pixel_offset(vec2(a_Position.y, a_Position.z)); // Mapbox || 高德 - vec2 limitedOffsetDistances = clamp( - offsetDistances, - project_pixel(-lengthCommon*.2), project_pixel(lengthCommon*.2) + vec2 limitedOffsetDistances = clamp( + offsetDistances, + project_pixel(-lengthCommon * 0.2), + project_pixel(lengthCommon * 0.2) ); - float startOffsetCommon = project_pixel(offsets[0]); float endOffsetCommon = project_pixel(offsets[1]); float endpointOffset = mix( - clamp(startOffsetCommon, 0.0, lengthCommon*.2), - -clamp(endOffsetCommon, 0.0, lengthCommon*.2), + clamp(startOffsetCommon, 0.0, lengthCommon * 0.2), + -clamp(endOffsetCommon, 0.0, lengthCommon * 0.2), a_Position.x ); - vec2 normalsCommon = u_stroke_width * project_pixel_offset(vec2(a_Normal.x, a_Normal.y)); // mapbox || 高德 + vec2 normalsCommon = u_stroke_width * project_pixel_offset(vec2(a_Normal.x, a_Normal.y)); - float gapCommon = flag_gap() * project_pixel(u_gap_width); + float gapCommon = -1. * project_pixel(u_gap_width); vec3 offsetCommon = vec3( flowlineDir * (limitedOffsetDistances[1] + normalsCommon.y + endpointOffset * 1.05) - - perpendicularDir * (limitedOffsetDistances[0] + gapCommon + normalsCommon.x), + perpendicularDir * (limitedOffsetDistances[0] + gapCommon + normalsCommon.x), 0.0 ); - vec4 project_pos = project_position(vec4(position.xy, 0, 1.0)); + vec4 project_pos = project_position(vec4(position.xy, 0, 1.0), position64Low); vec4 fillColor = vec4(a_Color.rgb, a_Color.a * opacity); v_color = mix(fillColor, vec4(u_stroke.xyz, u_stroke.w * fillColor.w * u_stroke_opacity), a_Normal.z); - gl_Position = project_common_position_to_clipspace_v2(vec4(project_pos.xy + offsetCommon.xy, 0., 1.0)); - - + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offsetCommon.xy, 0., 1.0)); setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/line/shaders/greatCircle/line_arc_great_circle_frag.glsl b/packages/layers/src/line/shaders/greatCircle/line_arc_great_circle_frag.glsl index 8b60640cbff..ff7eeee2471 100644 --- a/packages/layers/src/line/shaders/greatCircle/line_arc_great_circle_frag.glsl +++ b/packages/layers/src/line/shaders/greatCircle/line_arc_great_circle_frag.glsl @@ -19,11 +19,11 @@ layout(std140) uniform commonUniorm { float u_linearColor: 0; }; -in vec4 v_line_data; -in vec2 v_iconMapUV; in vec4 v_dash_array; -in float v_distance_ratio; in vec4 v_color; +in vec2 v_iconMapUV; +in vec4 v_line_data; +in float v_distance_ratio; out vec4 outputColor; #pragma include "picking" @@ -34,7 +34,7 @@ void main() { float animateSpeed = 0.0; float d_segmentIndex = v_line_data.g; - + // 设置弧线的底色 if(u_linearColor == 1.0) { // 使用渐变颜色 outputColor = mix(u_sourceColor, u_targetColor, d_segmentIndex/segmentNumber); @@ -65,7 +65,7 @@ void main() { } // 设置弧线的贴图 - if(LineTexture == u_line_texture && u_line_type != LineTypeDash) { + if(LineTexture == u_line_texture && u_line_type != LineTypeDash) { float arcRadio = smoothstep( 0.0, 1.0, (d_segmentIndex / (segmentNumber - 1.0))); // float arcRadio = d_segmentIndex / (segmentNumber - 1.0); float count = v_line_data.b; // 贴图在弧线上重复的数量 @@ -79,7 +79,7 @@ void main() { vec2 uv= v_iconMapUV / u_textSize + vec2(u, v) / u_textSize * 64.; vec4 pattern = texture(SAMPLER_2D(u_texture), uv); - + // 设置贴图和底色的叠加模式 if(u_textureBlend == 0.0) { // normal pattern.a = 0.0; @@ -96,4 +96,4 @@ void main() { } // gl_FragColor = filterColor(gl_FragColor); -} \ No newline at end of file +} diff --git a/packages/layers/src/line/shaders/greatCircle/line_arc_great_circle_vert.glsl b/packages/layers/src/line/shaders/greatCircle/line_arc_great_circle_vert.glsl index ffbac484068..25da830d08f 100644 --- a/packages/layers/src/line/shaders/greatCircle/line_arc_great_circle_vert.glsl +++ b/packages/layers/src/line/shaders/greatCircle/line_arc_great_circle_vert.glsl @@ -1,13 +1,14 @@ -#define LineTypeSolid 0.0 -#define LineTypeDash 1.0 -#define Animate 0.0 -#define LineTexture 1.0 - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in float a_Size; -layout(location = 12) in vec4 a_Instance; -layout(location = 14) in vec2 a_iconMapUV; +#define LineTypeSolid (0.0) +#define LineTypeDash (1.0) +#define Animate (0.0) +#define LineTexture (1.0) + +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in float a_Size; +layout(location = ATTRIBUTE_LOCATION_INSTANCE) in vec4 a_Instance; +layout(location = ATTRIBUTE_LOCATION_INSTANCE_64LOW) in vec4 a_Instance64Low; +layout(location = ATTRIBUTE_LOCATION_UV) in vec2 a_iconMapUV; layout(std140) uniform commonUniorm { vec4 u_animate: [ 1., 2., 1.0, 0.2 ]; @@ -34,12 +35,12 @@ out float v_distance_ratio; #pragma include "project" #pragma include "picking" -float maps (float value, float start1, float stop1, float start2, float stop2) { +float maps(float value, float start1, float stop1, float start2, float stop2) { return start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1)); } float getSegmentRatio(float index) { - return index / (segmentNumber - 1.); + return index / (segmentNumber - 1.0); } float paraboloid(vec2 source, vec2 target, float ratio) { @@ -53,33 +54,29 @@ float paraboloid(vec2 source, vec2 target, float ratio) { vec3 getPos(vec2 source, vec2 target, float segmentRatio) { float vertex_height = paraboloid(source, target, segmentRatio); - return vec3( - mix(source, target, segmentRatio), - sqrt(max(0.0, vertex_height)) - ); + return vec3(mix(source, target, segmentRatio), sqrt(max(0.0, vertex_height))); } vec2 getExtrusionOffset(vec2 line_clipspace, float offset_direction) { // normalized direction of the line vec2 dir_screenspace = normalize(line_clipspace); // rotate by 90 degrees - dir_screenspace = vec2(-dir_screenspace.y, dir_screenspace.x); - vec2 offset = dir_screenspace * offset_direction * setPickingSize(a_Size)/ 2.0; + dir_screenspace = vec2(-dir_screenspace.y, dir_screenspace.x); + vec2 offset = dir_screenspace * offset_direction * setPickingSize(a_Size) / 2.0; return offset; } vec2 getNormal(vec2 line_clipspace, float offset_direction) { // normalized direction of the line vec2 dir_screenspace = normalize(line_clipspace); // rotate by 90 degrees - dir_screenspace = vec2(-dir_screenspace.y, dir_screenspace.x); - return reverse_offset_normal(vec3(dir_screenspace,1.0)).xy * sign(offset_direction); + dir_screenspace = vec2(-dir_screenspace.y, dir_screenspace.x); + return dir_screenspace.xy * sign(offset_direction); } -float getAngularDist (vec2 source, vec2 target) { +float getAngularDist(vec2 source, vec2 target) { vec2 delta = source - target; vec2 sin_half_delta = sin(delta / 2.0); float a = sin_half_delta.y * sin_half_delta.y + - cos(source.y) * cos(target.y) * - sin_half_delta.x * sin_half_delta.x; + cos(source.y) * cos(target.y) * sin_half_delta.x * sin_half_delta.x; return 2.0 * atan(sqrt(a), sqrt(1.0 - a)); } @@ -90,37 +87,29 @@ vec2 midPoint(vec2 source, vec2 target) { float thetaOffset = 0.314; float r2 = r / 2.0 / cos(thetaOffset); float theta2 = theta + thetaOffset; - vec2 mid = vec2(r2*cos(theta2) + source.x, r2*sin(theta2) + source.y); + vec2 mid = vec2(r2 * cos(theta2) + source.x, r2 * sin(theta2) + source.y); return mid; } float bezier3(vec3 arr, float t) { - float ut = 1. - t; + float ut = 1.0 - t; return (arr.x * ut + arr.y * t) * ut + (arr.y * ut + arr.z * t) * t; } -vec2 interpolate (vec2 source, vec2 target, float angularDist, float t) { - // if the angularDist is PI, linear interpolation is applied. otherwise, use spherical interpolation - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x - vec2 mid = midPoint(source, target); - vec3 x = vec3(source.x, mid.x, target.x); - vec3 y = vec3(source.y, mid.y, target.y); - return vec2(bezier3(x ,t), bezier3(y,t)); - } - else { - if(abs(angularDist - PI) < 0.001) { - return (1.0 - t) * source + t * target; - } - float a = sin((1.0 - t) * angularDist) / sin(angularDist); - float b = sin(t * angularDist) / sin(angularDist); - vec2 sin_source = sin(source); - vec2 cos_source = cos(source); - vec2 sin_target = sin(target); - vec2 cos_target = cos(target); - float x = a * cos_source.y * cos_source.x + b * cos_target.y * cos_target.x; - float y = a * cos_source.y * sin_source.x + b * cos_target.y * sin_target.x; - float z = a * sin_source.y + b * sin_target.y; - return vec2(atan(y, x), atan(z, sqrt(x * x + y * y))); +vec2 interpolate(vec2 source, vec2 target, float angularDist, float t) { + if (abs(angularDist - PI) < 0.001) { + return (1.0 - t) * source + t * target; } + float a = sin((1.0 - t) * angularDist) / sin(angularDist); + float b = sin(t * angularDist) / sin(angularDist); + vec2 sin_source = sin(source); + vec2 cos_source = cos(source); + vec2 sin_target = sin(target); + vec2 cos_target = cos(target); + float x = a * cos_source.y * cos_source.x + b * cos_target.y * cos_target.x; + float y = a * cos_source.y * sin_source.x + b * cos_target.y * sin_target.x; + float z = a * sin_source.y + b * sin_target.y; + return vec2(atan(y, x), atan(z, sqrt(x * x + y * y))); + } void main() { @@ -133,54 +122,44 @@ void main() { float segmentRatio = getSegmentRatio(segmentIndex); float indexDir = mix(-1.0, 1.0, step(segmentIndex, 0.0)); - if(u_line_type == LineTypeDash) { + if (u_line_type == LineTypeDash) { v_distance_ratio = segmentIndex / segmentNumber; - vec2 s = source; - vec2 t = target; - - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x - s = unProjCustomCoord(source); - t = unProjCustomCoord(target); - } - float total_Distance = pixelDistance(s, t) / 2.0 * PI; - total_Distance = total_Distance*16.0; // total_Distance*16.0 调整默认的效果 + float total_Distance = pixelDistance(source, target) / 2.0 * PI; + total_Distance = total_Distance * 16.0; // total_Distance*16.0 调整默认的效果 v_dash_array = pow(2.0, 20.0 - u_Zoom) * u_dash_array / total_Distance; } - if(u_animate.x == Animate) { - v_distance_ratio = segmentIndex / segmentNumber; + if (u_animate.x == Animate) { + v_distance_ratio = segmentIndex / segmentNumber; } float nextSegmentRatio = getSegmentRatio(segmentIndex + indexDir); v_distance_ratio = segmentIndex / segmentNumber; - vec4 curr = project_position(vec4(degrees(interpolate(source, target, angularDist, segmentRatio)), 0.0, 1.0)); - vec4 next = project_position(vec4(degrees(interpolate(source, target, angularDist, nextSegmentRatio)), 0.0, 1.0)); + + vec4 curr = project_position(vec4(degrees(interpolate(source, target, angularDist, segmentRatio)), 0.0, 1.0), a_Instance64Low.xy); + vec4 next = project_position(vec4(degrees(interpolate(source, target, angularDist, nextSegmentRatio)), 0.0, 1.0), a_Instance64Low.zw); + // v_normal = getNormal((next.xy - curr.xy) * indexDir, a_Position.y); vec2 offset = project_pixel(getExtrusionOffset((next.xy - curr.xy) * indexDir, a_Position.y)); // vec4 project_pos = project_position(vec4(curr.xy, 0, 1.0)); // gl_Position = project_common_position_to_clipspace(vec4(curr.xy + offset, curr.z, 1.0)); v_line_data.g = a_Position.x; // 该顶点在弧线上的分段排序 - if(LineTexture == u_line_texture) { // 开启贴图模式 - // float mapZoomScale = u_CoordinateSystem !== COORDINATE_SYSTEM_P20_2?10000000.0:1.0; + if (LineTexture == u_line_texture) { float d_arcDistrance = length(source - target); - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20) { // amap - d_arcDistrance = d_arcDistrance * 1000000.0; - } - if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { // mapbox - d_arcDistrance = project_pixel_allmap(d_arcDistrance); - } - float d_pixelLen = project_pixel(u_icon_step)/8.0; - v_line_data.b = floor(d_arcDistrance/d_pixelLen); // 贴图在弧线上重复的数量 + d_arcDistrance = project_pixel(d_arcDistrance); + + float d_pixelLen = project_pixel(u_icon_step) / 8.0; + v_line_data.b = floor(d_arcDistrance / d_pixelLen); // 贴图在弧线上重复的数量 float lineOffsetWidth = length(offset + offset * sign(a_Position.y)); // 线横向偏移的距离 - float linePixelSize = project_pixel(a_Size); // 定点位置偏移,按地图等级缩放后的距离 - v_line_data.a = lineOffsetWidth/linePixelSize; // 线图层贴图部分的 v 坐标值 + float linePixelSize = project_pixel(a_Size); // 定点位置偏移,按地图等级缩放后的距离 + v_line_data.a = lineOffsetWidth / linePixelSize; // 线图层贴图部分的 v 坐标值 v_iconMapUV = a_iconMapUV; } - gl_Position = project_common_position_to_clipspace_v2(vec4(curr.xy + offset, 0, 1.0)); + gl_Position = project_common_position_to_clipspace(vec4(curr.xy + offset, 0, 1.0)); setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/line/shaders/line/line_vert.glsl b/packages/layers/src/line/shaders/line/line_vert.glsl index 552de2af110..ac2d4116638 100644 --- a/packages/layers/src/line/shaders/line/line_vert.glsl +++ b/packages/layers/src/line/shaders/line/line_vert.glsl @@ -1,12 +1,12 @@ +#define Animate (0.0) -#define Animate 0.0 - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in vec2 a_Size; -layout(location = 10) in vec3 a_DistanceAndIndexAndMiter; -layout(location = 13) in vec4 a_Normal_Total_Distance; -layout(location = 14) in vec2 a_iconMapUV; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_POSITION_64LOW) in vec2 a_Position64Low; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in vec2 a_Size; +layout(location = ATTRIBUTE_LOCATION_DISTANCE_INDEX) in vec3 a_DistanceAndIndexAndMiter; +layout(location = ATTRIBUTE_LOCATION_NORMAL) in vec4 a_Normal_Total_Distance; +layout(location = ATTRIBUTE_LOCATION_UV) in vec2 a_iconMapUV; layout(std140) uniform commonUniorm { vec4 u_animate: [ 1., 2., 1.0, 0.2 ]; @@ -27,7 +27,6 @@ layout(std140) uniform commonUniorm { float u_time; }; - out vec4 v_color; out vec4 v_stroke; //dash @@ -50,69 +49,53 @@ void main() { v_d_distance_ratio = a_DistanceAndIndex.x / a_Total_Distance; // cal style mapping - 数据纹理映射部分的计算 - float d_texPixelLen; // 贴图的像素长度,根据地图层级缩放 + float d_texPixelLen; // 贴图的像素长度,根据地图层级缩放 v_iconMapUV = a_iconMapUV; d_texPixelLen = project_float_pixel(u_icon_step); - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { - d_texPixelLen *= 10.0; - } v_color = a_Color; v_color.a *= opacity; v_stroke = stroke; - vec3 size = a_Miter * setPickingSize(a_Size.x) * reverse_offset_normal(a_Normal); - + vec3 size = a_Miter * setPickingSize(a_Size.x) * a_Normal; + vec2 offset = project_pixel(size.xy); float lineDistance = a_DistanceAndIndex.x; float currentLinePointRatio = lineDistance / a_Total_Distance; - float lineOffsetWidth = length(offset + offset * sign(a_Miter)); // 线横向偏移的距离(向两侧偏移的和) - float linePixelSize = project_pixel(a_Size.x) * 2.0; // 定点位置偏移,按地图等级缩放后的距离 单侧 * 2 - float texV = lineOffsetWidth/linePixelSize; // 线图层贴图部分的 v 坐标值 - + float linePixelSize = project_pixel(a_Size.x) * 2.0; // 定点位置偏移,按地图等级缩放后的距离 单侧 * 2 + float texV = lineOffsetWidth / linePixelSize; // 线图层贴图部分的 v 坐标值 + v_texture_data = vec4(currentLinePointRatio, lineDistance, d_texPixelLen, texV); // 设置数据集的参数 - vec4 project_pos = project_position(vec4(a_Position.xy, 0, 1.0)); + vec4 project_pos = project_position(vec4(a_Position.xy, 0, 1.0), a_Position64Low); // gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, a_Size.y, 1.0)); float h = float(a_Position.z) * u_vertexScale; // 线顶点的高度 - 兼容不存在第三个数值的情况 vertex height float lineHeight = a_Size.y; // size 第二个参数代表的高度 [linewidth, lineheight] - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x - lineHeight *= 0.2; // 保持和 amap/mapbox 一致的效果 - h *= 0.2; - if(u_heightfixed < 1.0) { - lineHeight = project_pixel(a_Size.y); - } - gl_Position = u_Mvp * (vec4(project_pos.xy + offset, lineHeight + h + u_raisingHeight, 1.0)); - } else { - // 兼容 mapbox 在线高度上的效果表现基本一致 - if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { - // mapbox - // 保持高度相对不变 - float mapboxZoomScale = 4.0/pow(2.0, 21.0 - u_Zoom); - h *= mapboxZoomScale; - h += u_raisingHeight * mapboxZoomScale; - if(u_heightfixed > 0.0) { - lineHeight *= mapboxZoomScale; - } - - } else { - // amap - h += u_raisingHeight; - // lineHeight 顶点偏移高度 - if(u_heightfixed < 1.0) { - lineHeight *= pow(2.0, 20.0 - u_Zoom); - } + // 兼容 mapbox 在线高度上的效果表现基本一致 + if ( + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET + ) { + // mapbox + // 保持高度相对不变 + float mapboxZoomScale = 4.0 / pow(2.0, 21.0 - u_Zoom); + h *= mapboxZoomScale; + h += u_raisingHeight * mapboxZoomScale; + if (u_heightfixed > 0.0) { + lineHeight *= mapboxZoomScale; } - - gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, lineHeight + h, 1.0)); } + gl_Position = project_common_position_to_clipspace( + vec4(project_pos.xy + offset, lineHeight + h, 1.0) + ); + setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/line/shaders/simple/simpleline_vert.glsl b/packages/layers/src/line/shaders/simple/simpleline_vert.glsl index ceba6107a6b..c78dbd671ed 100644 --- a/packages/layers/src/line/shaders/simple/simpleline_vert.glsl +++ b/packages/layers/src/line/shaders/simple/simpleline_vert.glsl @@ -1,6 +1,7 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in vec4 a_SizeDistanceAndTotalDistance; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_POSITION_64LOW) in vec2 a_Position64Low; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in vec4 a_SizeDistanceAndTotalDistance; layout(std140) uniform commonUniorm { vec4 u_sourceColor; @@ -21,30 +22,24 @@ void main() { //dash输出 v_dash_array = pow(2.0, 20.0 - u_Zoom) * u_dash_array / a_SizeDistanceAndTotalDistance.a; - v_color = a_Color; + v_color = a_Color; v_distanceScale = a_SizeDistanceAndTotalDistance.b / a_SizeDistanceAndTotalDistance.a; v_color.a = v_color.a * opacity; - vec4 project_pos = project_position(vec4(a_Position.xy, 0, 1.0)); + vec4 project_pos = project_position(vec4(a_Position.xy, 0, 1.0), a_Position64Low); float h = float(a_Position.z) * u_vertexScale; // 线顶点的高度 - 兼容不存在第三个数值的情况 - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x - gl_Position = u_Mvp * (vec4(project_pos.xy, project_pixel(a_SizeDistanceAndTotalDistance.y) + h * 0.2, 1.0)); - } else { - float lineHeight = a_SizeDistanceAndTotalDistance.y; - // 兼容 mapbox 在线高度上的效果表现基本一致 - if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { - // 保持高度相对不变 - h *= 2.0/pow(2.0, 20.0 - u_Zoom); - } - - // amap1.x - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) { - // 保持高度相对不变 - lineHeight *= pow(2.0, 20.0 - u_Zoom); - } - - gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy, lineHeight + h, 1.0)); - gl_PointSize = 10.0; + float lineHeight = a_SizeDistanceAndTotalDistance.y; + // 兼容 mapbox 在线高度上的效果表现基本一致 + if ( + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET + ) { + // 保持高度相对不变 + h *= 2.0 / pow(2.0, 20.0 - u_Zoom); } + + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy, lineHeight + h, 1.0)); + gl_PointSize = 10.0; + } diff --git a/packages/layers/src/line/shaders/wall/wall_frag.glsl b/packages/layers/src/line/shaders/wall/wall_frag.glsl index 7c52c3ad192..89ae85c656b 100644 --- a/packages/layers/src/line/shaders/wall/wall_frag.glsl +++ b/packages/layers/src/line/shaders/wall/wall_frag.glsl @@ -17,13 +17,15 @@ layout(std140) uniform commonUniorm { float u_iconStepCount; float u_time; }; + + in vec2 v_iconMapUV; -in float v_blur; -in float v_radio; in vec4 v_color; +in float v_blur; in vec4 v_dataset; out vec4 outputColor; + #pragma include "picking" void main() { @@ -79,7 +81,7 @@ void main() { outputColor = filterColor(pattern); } } - + // blur - AA if(v < v_blur) { diff --git a/packages/layers/src/line/shaders/wall/wall_vert.glsl b/packages/layers/src/line/shaders/wall/wall_vert.glsl index 83c9eb92558..3f710f6557a 100644 --- a/packages/layers/src/line/shaders/wall/wall_vert.glsl +++ b/packages/layers/src/line/shaders/wall/wall_vert.glsl @@ -1,14 +1,11 @@ #define Animate 0.0 -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in vec2 a_Size; -layout(location = 10) in float a_Miter; -layout(location = 11) in float a_Total_Distance; -layout(location = 12) in vec4 a_Instance; -layout(location = 13) in vec3 a_Normal; -layout(location = 14) in vec2 a_iconMapUV; -layout(location = 15) in float a_Distance; - +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_POSITION_64LOW) in vec2 a_Position64Low; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in vec2 a_Size; +layout(location = ATTRIBUTE_LOCATION_NORMAL) in vec3 a_Normal; +layout(location = ATTRIBUTE_LOCATION_UV) in vec2 a_iconMapUV; +layout(location = ATTRIBUTE_LOCATION_DISTANCE_MITER_TOTAL) in vec3 a_Distance_Total_Miter; layout(std140) uniform commonUniorm { vec4 u_animate: [ 1., 2., 1.0, 0.2 ]; @@ -23,78 +20,71 @@ layout(std140) uniform commonUniorm { float u_iconStepCount; float u_time; }; -#pragma include "projection" -#pragma include "light" -#pragma include "picking" // texV 线图层 - 贴图部分的 v 坐标(线的宽度方向) out vec2 v_iconMapUV; out vec4 v_color; out float v_blur; -out float v_radio; out vec4 v_dataset; -void main() { +#pragma include "projection" +#pragma include "light" +#pragma include "picking" +void main() { + float a_Distance = a_Distance_Total_Miter.x; + float a_Miter = a_Distance_Total_Miter.y; + float a_Total_Distance = a_Distance_Total_Miter.z; float d_distance_ratio; // 当前点位距离占线总长的比例 - float d_texPixelLen; // 贴图的像素长度,根据地图层级缩放 + float d_texPixelLen; // 贴图的像素长度,根据地图层级缩放 v_iconMapUV = a_iconMapUV; - if(u_heightfixed < 1.0) { // 高度随 zoom 调整 + if (u_heightfixed < 1.0) { + // 高度随 zoom 调整 d_texPixelLen = project_pixel(u_icon_step); } else { d_texPixelLen = u_icon_step; } - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { - d_texPixelLen *= 10.0; - } - if(u_animate.x == Animate || u_linearColor == 1.0) { - d_distance_ratio = a_Distance / a_Total_Distance; + if (u_animate.x == Animate || u_linearColor == 1.0) { + d_distance_ratio = a_Distance / a_Total_Distance; } - float miter = (a_Miter + 1.0)/2.0; + float miter = (a_Miter + 1.0) / 2.0; // 设置数据集的参数 v_dataset[0] = d_distance_ratio; // 当前点位距离占线总长的比例 - v_dataset[1] = a_Distance; // 当前顶点的距离 - v_dataset[2] = d_texPixelLen; // 贴图的像素长度,根据地图层级缩放 - v_dataset[3] = miter; // 线图层贴图部分的 v 坐标值 0 - 1 + v_dataset[1] = a_Distance; // 当前顶点的距离 + v_dataset[2] = d_texPixelLen; // 贴图的像素长度,根据地图层级缩放 + v_dataset[3] = miter; // 线图层贴图部分的 v 坐标值 0 - 1 - vec4 project_pos = project_position(vec4(a_Position.xy, 0, 1.0)); + vec4 project_pos = project_position(vec4(a_Position.xy, 0, 1.0), a_Position64Low); - float originSize = a_Size.x; // 固定高度 - if(u_heightfixed < 1.0) { - originSize = project_float_meter(a_Size.x); // 高度随 zoom 调整 + float originSize = a_Size.x; // 固定高度 + if (u_heightfixed < 1.0) { + originSize = project_float_meter(a_Size.x); // 高度随 zoom 调整 } - float wallHeight = originSize * miter; float lightWeight = calc_lighting(vec4(project_pos.xy, wallHeight, 1.0)); v_blur = min(project_float_pixel(2.0) / originSize, 0.05); v_color = vec4(a_Color.rgb * lightWeight, a_Color.w * opacity); - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x - gl_Position = u_Mvp * (vec4(project_pos.xy, wallHeight, 1.0)); - } else { -// 兼容 mapbox 在线高度上的效果表现基本一致 - if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { - // mapbox - // 保持高度相对不变 - float mapboxZoomScale = 4.0 / pow(2.0, 21.0 - u_Zoom); - if(u_heightfixed > 0.0) { - wallHeight *= mapboxZoomScale; - } - - } else { - // lineHeight 顶点偏移高度 - if(u_heightfixed < 1.0) { - wallHeight *= pow(2.0, 20.0 - u_Zoom); - } + // 兼容 mapbox 在线高度上的效果表现基本一致 + if ( + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET + ) { + // mapbox + // 保持高度相对不变 + float mapboxZoomScale = 4.0 / pow(2.0, 21.0 - u_Zoom); + if (u_heightfixed > 0.0) { + wallHeight *= mapboxZoomScale; } - gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy, wallHeight, 1.0)); } + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy, wallHeight, 1.0)); + setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/mask/models/fill.ts b/packages/layers/src/mask/models/fill.ts index 43687b43fbb..740e139fe50 100644 --- a/packages/layers/src/mask/models/fill.ts +++ b/packages/layers/src/mask/models/fill.ts @@ -40,6 +40,7 @@ export default class MaskModel extends BaseModel { moduleName: 'mask', vertexShader: mask_vert, fragmentShader: mask_frag, + defines: this.getDefines(), triangulation: polygonTriangulation, depth: { enable: false }, pick: false, diff --git a/packages/layers/src/mask/shaders/mask_vert.glsl b/packages/layers/src/mask/shaders/mask_vert.glsl index 4a6b6b749b9..9710b618f84 100644 --- a/packages/layers/src/mask/shaders/mask_vert.glsl +++ b/packages/layers/src/mask/shaders/mask_vert.glsl @@ -1,4 +1,4 @@ -layout(location = 0) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; layout(std140) uniform commonUniorm { vec4 u_color; @@ -9,11 +9,6 @@ layout(std140) uniform commonUniorm { void main() { vec4 project_pos = project_position(vec4(a_Position, 1.0)); - - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x - gl_Position = u_Mvp * (vec4(project_pos.xyz, 1.0)); - } else { - gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); - } + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); } diff --git a/packages/layers/src/plugins/DataMappingPlugin.ts b/packages/layers/src/plugins/DataMappingPlugin.ts index da2072fd4b1..a052d253970 100644 --- a/packages/layers/src/plugins/DataMappingPlugin.ts +++ b/packages/layers/src/plugins/DataMappingPlugin.ts @@ -11,8 +11,7 @@ import type { Position, } from '@antv/l7-core'; import { IDebugLog, ILayerStage } from '@antv/l7-core'; -import { lodashUtil, normalize, rgb2arr } from '@antv/l7-utils'; -const { cloneDeep } = lodashUtil; +import { normalize, rgb2arr } from '@antv/l7-utils'; export default class DataMappingPlugin implements ILayerPlugin { private mapService: IMapService; @@ -151,37 +150,12 @@ export default class DataMappingPlugin implements ILayerPlugin { attributes.forEach((attribute) => { attribute.needRemapping = false; }); - // 调整数据兼容 Amap2.0 - this.adjustData2Amap2Coordinates(mappedData, layer); // 调整数据兼容 SimpleCoordinates this.adjustData2SimpleCoordinates(mappedData); return mappedData; } - private adjustData2Amap2Coordinates(mappedData: IEncodeFeature[], layer: ILayer) { - // 根据地图的类型判断是否需要对点位数据进行处理, 若是高德2.0则需要对坐标进行相对偏移 - if (mappedData.length > 0 && this.mapService.version === 'GAODE2.x') { - const layerCenter = layer.coordCenter || layer.getSource().center; - // 单个的点数据 - // @ts-ignore - mappedData - // TODO: 避免经纬度被重复计算导致坐标位置偏移 - .filter((d) => !d.originCoordinates) - .map((d) => { - d.version = 'GAODE2.x'; - // @ts-ignore - d.originCoordinates = cloneDeep(d.coordinates); // 为了兼容高德1.x 需要保存一份原始的经纬度坐标数据(许多上层逻辑依赖经纬度数据) - // @ts-ignore - // d.coordinates = this.mapService.lngLatToCoord(d.coordinates); - d.coordinates = this.mapService.coordToAMap2RelativeCoordinates( - d.coordinates, - layerCenter, - ); - }); - } - } - private adjustData2SimpleCoordinates(mappedData: IEncodeFeature[]) { if (mappedData.length > 0 && this.mapService.version === 'SIMPLE') { mappedData.map((d) => { diff --git a/packages/layers/src/plugins/PixelPickingPlugin.ts b/packages/layers/src/plugins/PixelPickingPlugin.ts index 49096ff25ab..f032261fcba 100644 --- a/packages/layers/src/plugins/PixelPickingPlugin.ts +++ b/packages/layers/src/plugins/PixelPickingPlugin.ts @@ -1,7 +1,7 @@ import type { IEncodeFeature, ILayer, ILayerPlugin, L7Container } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; import { decodePickingColor, encodePickingColor, lodashUtil, rgb2arr } from '@antv/l7-utils'; -import { ShaderLocation } from '../core/CommonStyleAttribute'; +import { COMMON_ATTRIBUTE_LOCATION } from '../core/CommonStyleAttribute'; const { isNumber } = lodashUtil; const PickingStage = { @@ -67,7 +67,7 @@ export default class PixelPickingPlugin implements ILayerPlugin { type: AttributeType.Attribute, descriptor: { name: 'a_PickingColor', - shaderLocation: ShaderLocation.PICKING_COLOR, + shaderLocation: COMMON_ATTRIBUTE_LOCATION.PICKING_COLOR, buffer: { data: [], type: gl.FLOAT, diff --git a/packages/layers/src/plugins/RegisterStyleAttributePlugin.ts b/packages/layers/src/plugins/RegisterStyleAttributePlugin.ts index d253cee420e..5c81f7a47ae 100644 --- a/packages/layers/src/plugins/RegisterStyleAttributePlugin.ts +++ b/packages/layers/src/plugins/RegisterStyleAttributePlugin.ts @@ -6,7 +6,7 @@ import type { L7Container, } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; -import { ShaderLocation } from '../core/CommonStyleAttribute'; +import { COMMON_ATTRIBUTE_LOCATION } from '../core/CommonStyleAttribute'; import { isTileGroup } from '../tile/utils/utils'; /** @@ -34,7 +34,6 @@ export default class RegisterStyleAttributePlugin implements ILayerPlugin { this.registerPositionAttribute(styleAttributeService); // this.registerFilterAttribute(styleAttributeService);//数据层数据过滤 this.registerColorAttribute(styleAttributeService); - this.registerVertexIdAttribute(styleAttributeService); } private registerPositionAttribute(styleAttributeService: IStyleAttributeService) { @@ -43,7 +42,7 @@ export default class RegisterStyleAttributePlugin implements ILayerPlugin { type: AttributeType.Attribute, descriptor: { name: 'a_Position', - shaderLocation: ShaderLocation.POSITION, + shaderLocation: COMMON_ATTRIBUTE_LOCATION.POSITION, buffer: { data: [], type: gl.FLOAT, @@ -64,7 +63,7 @@ export default class RegisterStyleAttributePlugin implements ILayerPlugin { type: AttributeType.Attribute, descriptor: { name: 'a_Color', - shaderLocation: ShaderLocation.COLOR, + shaderLocation: COMMON_ATTRIBUTE_LOCATION.COLOR, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, @@ -79,26 +78,4 @@ export default class RegisterStyleAttributePlugin implements ILayerPlugin { }, }); } - - private registerVertexIdAttribute(styleAttributeService: IStyleAttributeService) { - styleAttributeService.registerStyleAttribute({ - // 统一注册每个顶点的唯一编号(目前用于样式的数据映射计算使用) - name: 'vertexId', - type: AttributeType.Attribute, - descriptor: { - name: 'a_vertexId', - shaderLocation: ShaderLocation.VERTEX_ID, - buffer: { - // give the WebGL driver a hint that this buffer may change - usage: gl.DYNAMIC_DRAW, - data: [], - type: gl.FLOAT, - }, - size: 1, - update: (feature: IEncodeFeature, featureIdx: number) => { - return [featureIdx]; - }, - }, - }); - } } diff --git a/packages/layers/src/plugins/ShaderUniformPlugin.ts b/packages/layers/src/plugins/ShaderUniformPlugin.ts index e8c89c6465c..e6e2e1b42d5 100644 --- a/packages/layers/src/plugins/ShaderUniformPlugin.ts +++ b/packages/layers/src/plugins/ShaderUniformPlugin.ts @@ -41,17 +41,13 @@ export default class ShaderUniformPlugin implements ILayerPlugin { this.coordinateSystemService = coordinateSystemService; this.cameraService = cameraService; - const version = this.mapService.version; - - let mvp = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; // default matrix (for gaode2.x) - let sceneCenterMercator: [number, number] = [0, 0]; - let uniformBuffer: IBuffer; if (!this.rendererService.uniformBuffers[0]) { // Create a Uniform Buffer Object(UBO). uniformBuffer = this.rendererService.createBuffer({ data: new Float32Array(16 * 4 + 4 * 7), isUBO: true, + label: 'renderUniformBuffer', }); this.rendererService.uniformBuffers[0] = uniformBuffer; } @@ -61,23 +57,9 @@ export default class ShaderUniformPlugin implements ILayerPlugin { const offset = layer.getLayerConfig().tileOrigin; // 重新计算坐标系参数 this.coordinateSystemService.refresh(offset); - if (version === 'GAODE2.x') { - this.setLayerCenter(layer); - // @ts-ignore - mvp = this.mapService.map.customCoords.getMVPMatrix(); - // mvp = amapCustomCoords.getMVPMatrix() - // @ts-ignore - sceneCenterMercator = this.mapService.getCustomCoordCenter(); - const uniformBuffer = layer.getLayerUniformBuffer(); - uniformBuffer.subData({ - offset: 0, - data: new Uint8Array(new Float32Array([...mvp, ...sceneCenterMercator]).buffer), - }); - } - const { width, height } = this.rendererService.getViewportSize(); - const { data, uniforms } = this.generateUBO(mvp, sceneCenterMercator, width, height); + const { data, uniforms } = this.generateUBO(width, height); if (this.layerService.alreadyInRendering && this.rendererService.uniformBuffers[0]) { const renderUniformBuffer = this.rendererService.uniformBuffers[0]; // Update only once since all models can share one UBO. @@ -103,25 +85,7 @@ export default class ShaderUniformPlugin implements ILayerPlugin { }); } - /** - * 对于每个 layer 都有不同的几何中心点,因此在绘制每个 layer 的时候都需要重新设置 - * @param layer - */ - private setLayerCenter(layer: ILayer) { - if (layer.coordCenter === undefined) { - layer.coordCenter = layer.getSource().center; - } - if (this.mapService.setCoordCenter) { - this.mapService.setCoordCenter(layer.coordCenter); - } - } - - private generateUBO( - u_Mvp: number[], - sceneCenterMercator: [number, number], - width: number, - height: number, - ) { + private generateUBO(width: number, height: number) { const u_ProjectionMatrix = this.cameraService.getProjectionMatrix(); const u_ViewMatrix = this.cameraService.getViewMatrix(); const u_ViewProjectionMatrix = this.cameraService.getViewProjectionMatrix(); @@ -179,9 +143,6 @@ export default class ShaderUniformPlugin implements ILayerPlugin { [CoordinateUniform.PixelsPerDegree]: u_PixelsPerDegree, [CoordinateUniform.PixelsPerDegree2]: u_PixelsPerDegree2, [CoordinateUniform.PixelsPerMeter]: u_PixelsPerMeter, - // 坐标系是高德2.0的时候单独计算 - [CoordinateUniform.Mvp]: u_Mvp, - u_sceneCenterMercator: sceneCenterMercator, // 其他参数,例如视口大小、DPR 等 u_ViewportSize: u_ViewportSize, u_ModelMatrix, diff --git a/packages/layers/src/point/models/billboard_point.ts b/packages/layers/src/point/models/billboard_point.ts index c4023aabf01..41898a6de40 100644 --- a/packages/layers/src/point/models/billboard_point.ts +++ b/packages/layers/src/point/models/billboard_point.ts @@ -4,7 +4,6 @@ import BaseModel from '../../core/BaseModel'; import type { IPointLayerStyleOptions } from '../../core/interface'; import { rgb2arr } from '@antv/l7-utils'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import simplePointFrag from '../shaders/billboard/billboard_point_frag.glsl'; import simplePointVert from '../shaders/billboard/billboard_point_vert.glsl'; @@ -18,6 +17,13 @@ export function PointTriangulation(feature: IEncodeFeature) { } export default class SimplePointModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + SIZE: 9, + }); + } + public getDefaultStyle(): Partial { return { blend: 'additive', @@ -58,6 +64,7 @@ export default class SimplePointModel extends BaseModel { moduleName: 'pointSimple', vertexShader: simplePointVert, fragmentShader: simplePointFrag, + defines: this.getDefines(), inject: this.getInject(), triangulation: PointTriangulation, depth: { enable: false }, @@ -67,12 +74,15 @@ export default class SimplePointModel extends BaseModel { } protected registerBuiltinAttributes() { + // 注册 Position 属性 64 位地位部分,经纬度数据开启双精度,避免大于 22 层级以上出现数据偏移 + this.registerPosition64LowAttribute(); + this.styleAttributeService.registerStyleAttribute({ name: 'size', type: AttributeType.Attribute, descriptor: { name: 'a_Size', - shaderLocation: ShaderLocation.SIZE, + shaderLocation: this.attributeLocation.SIZE, buffer: { usage: gl.DYNAMIC_DRAW, data: [], diff --git a/packages/layers/src/point/models/earthExtrude.ts b/packages/layers/src/point/models/earthExtrude.ts index 6d1ca237d10..400b390e73c 100644 --- a/packages/layers/src/point/models/earthExtrude.ts +++ b/packages/layers/src/point/models/earthExtrude.ts @@ -1,8 +1,7 @@ import type { IEncodeFeature, ILayerConfig, IModel } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; -import { calculateCentroid, getCullFace, lodashUtil, rgb2arr } from '@antv/l7-utils'; +import { calculateCentroid, lodashUtil, rgb2arr } from '@antv/l7-utils'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import type { IPointLayerStyleOptions } from '../../core/interface'; import { PointExtrudeTriangulation } from '../../core/triangulation'; import { lglt2xyz } from '../../earth/utils'; @@ -10,6 +9,15 @@ import pointExtrudeFrag from '../shaders/earthExtrude/earthExtrude_frag.glsl'; import pointExtrudeVert from '../shaders/earthExtrude/earthExtrude_vert.glsl'; const { isNumber } = lodashUtil; export default class ExtrudeModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + SIZE: 9, + POS: 10, + NORMAL: 11, + }); + } + private raiseCount: number = 0; private raiseRepeat: number = 0; @@ -90,7 +98,6 @@ export default class ExtrudeModel extends BaseModel { } public async buildModels(): Promise { - // GAODE1.x GAODE2.x MAPBOX const { animateOption: { repeat = 1 }, } = this.layer.getLayerConfig() as ILayerConfig; @@ -102,10 +109,11 @@ export default class ExtrudeModel extends BaseModel { fragmentShader: pointExtrudeFrag, triangulation: PointExtrudeTriangulation, depth: { enable: true }, + defines: this.getDefines(), inject: this.getInject(), cull: { enable: true, - face: getCullFace(this.mapService.version), + face: gl.FRONT, }, blend: this.getBlend(), }); @@ -118,7 +126,7 @@ export default class ExtrudeModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Size', - shaderLocation: ShaderLocation.SIZE, + shaderLocation: this.attributeLocation.SIZE, buffer: { usage: gl.DYNAMIC_DRAW, data: [], @@ -149,7 +157,7 @@ export default class ExtrudeModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Normal', - shaderLocation: ShaderLocation.NORMAL, + shaderLocation: this.attributeLocation.NORMAL, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.STATIC_DRAW, @@ -173,7 +181,7 @@ export default class ExtrudeModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Pos', - shaderLocation: 15, + shaderLocation: this.attributeLocation.POS, buffer: { usage: gl.DYNAMIC_DRAW, data: [], diff --git a/packages/layers/src/point/models/earthFill.ts b/packages/layers/src/point/models/earthFill.ts index e036c529d87..680162545f0 100644 --- a/packages/layers/src/point/models/earthFill.ts +++ b/packages/layers/src/point/models/earthFill.ts @@ -8,8 +8,17 @@ import pointFillFrag from '../shaders/earthFill/earthFill_frag.glsl'; import pointFillVert from '../shaders/earthFill/earthFill_vert.glsl'; import { mat4, vec3 } from 'gl-matrix'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; + export default class FillModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + SIZE: 9, + SHAPE: 10, + EXTRUDE: 11, + }); + } + protected getCommonUniformsInfo(): { uniformsArray: number[]; uniformsLength: number; @@ -45,6 +54,7 @@ export default class FillModel extends BaseModel { vertexShader: pointFillVert, fragmentShader: pointFillFrag, triangulation: GlobelPointFillTriangulation, + defines: this.getDefines(), inject: this.getInject(), depth: { enable: true }, blend: this.getBlend(), @@ -62,7 +72,7 @@ export default class FillModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Extrude', - shaderLocation: ShaderLocation.EXTRUDE, + shaderLocation: this.attributeLocation.EXTRUDE, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, @@ -117,7 +127,7 @@ export default class FillModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Size', - shaderLocation: ShaderLocation.SIZE, + shaderLocation: this.attributeLocation.SIZE, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, @@ -138,7 +148,7 @@ export default class FillModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Shape', - shaderLocation: ShaderLocation.SHAPE, + shaderLocation: this.attributeLocation.SHAPE, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, diff --git a/packages/layers/src/point/models/extrude.ts b/packages/layers/src/point/models/extrude.ts index a229b493992..6893d545a4d 100644 --- a/packages/layers/src/point/models/extrude.ts +++ b/packages/layers/src/point/models/extrude.ts @@ -1,14 +1,22 @@ import type { IEncodeFeature, ILayerConfig, IModel } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; -import { calculateCentroid, getCullFace, rgb2arr } from '@antv/l7-utils'; +import { calculateCentroid, fp64LowPart, rgb2arr } from '@antv/l7-utils'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import type { IPointLayerStyleOptions } from '../../core/interface'; import { PointExtrudeTriangulation } from '../../core/triangulation'; import pointExtrudeFrag from '../shaders/extrude/extrude_frag.glsl'; import pointExtrudeVert from '../shaders/extrude/extrude_vert.glsl'; export default class ExtrudeModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + SIZE: 9, + EXTRUDE: 10, + NORMAL: 11, + }); + } + private raiseCount: number = 0; private raiseRepeat: number = 0; protected getCommonUniformsInfo(): { @@ -89,7 +97,6 @@ export default class ExtrudeModel extends BaseModel { } public async buildModels(): Promise { - // GAODE1.x GAODE2.x MAPBOX const { depth = true, animateOption: { repeat = 1 }, @@ -102,10 +109,11 @@ export default class ExtrudeModel extends BaseModel { vertexShader: pointExtrudeVert, fragmentShader: pointExtrudeFrag, triangulation: PointExtrudeTriangulation, + defines: this.getDefines(), inject: this.getInject(), cull: { enable: true, - face: getCullFace(this.mapService.version), + face: gl.FRONT, }, depth: { enable: depth, @@ -120,7 +128,7 @@ export default class ExtrudeModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Size', - shaderLocation: ShaderLocation.SIZE, + shaderLocation: this.attributeLocation.SIZE, buffer: { usage: gl.DYNAMIC_DRAW, data: [], @@ -145,13 +153,12 @@ export default class ExtrudeModel extends BaseModel { }, }); - // point layer size; this.styleAttributeService.registerStyleAttribute({ name: 'normal', type: AttributeType.Attribute, descriptor: { name: 'a_Normal', - shaderLocation: ShaderLocation.NORMAL, + shaderLocation: this.attributeLocation.NORMAL, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.STATIC_DRAW, @@ -170,22 +177,30 @@ export default class ExtrudeModel extends BaseModel { }, }, }); + this.styleAttributeService.registerStyleAttribute({ name: 'extrude', type: AttributeType.Attribute, descriptor: { name: 'a_Extrude', - shaderLocation: ShaderLocation.EXTRUDE, + shaderLocation: this.attributeLocation.EXTRUDE, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, data: [], type: gl.FLOAT, }, - size: 3, + size: 4, update: (feature: IEncodeFeature) => { const coordinates = calculateCentroid(feature.coordinates); - return [coordinates[0], coordinates[1], 0]; + // [lng, lat, lowLng, lowLat] + // low part for enabled double precision + return [ + coordinates[0], + coordinates[1], + fp64LowPart(coordinates[0]), + fp64LowPart(coordinates[1]), + ]; }, }, }); diff --git a/packages/layers/src/point/models/fill.ts b/packages/layers/src/point/models/fill.ts index 9ba7c5ce114..ad2c5537a25 100644 --- a/packages/layers/src/point/models/fill.ts +++ b/packages/layers/src/point/models/fill.ts @@ -9,7 +9,6 @@ import type { } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import { PointFillTriangulation } from '../../core/triangulation'; import pointFillFrag from '../shaders/fill/fill_frag.glsl'; @@ -19,6 +18,15 @@ import type { IPointLayerStyleOptions } from '../../core/interface'; import { SizeUnitType } from '../../core/interface'; export default class FillModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + SIZE: 9, + SHAPE: 10, + EXTRUDE: 11, + }); + } + protected getCommonUniformsInfo(): { uniformsArray: number[]; uniformsLength: number; @@ -83,6 +91,7 @@ export default class FillModel extends BaseModel { moduleName: type, vertexShader: vert, fragmentShader: frag, + defines: this.getDefines(), inject: this.getInject(), triangulation: PointFillTriangulation, depth: { enable: false }, @@ -114,12 +123,15 @@ export default class FillModel extends BaseModel { // 注册 Style 参与数据映射的内置属性 const shape2d = this.layer.getLayerConfig().shape2d as string[]; + // 注册 Position 属性 64 位地位部分,经纬度数据开启双精度,避免大于 20层级以上出现数据偏移 + this.registerPosition64LowAttribute(); + this.styleAttributeService.registerStyleAttribute({ name: 'extrude', type: AttributeType.Attribute, descriptor: { name: 'a_Extrude', - shaderLocation: ShaderLocation.EXTRUDE, + shaderLocation: this.attributeLocation.EXTRUDE, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, @@ -146,7 +158,7 @@ export default class FillModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Size', - shaderLocation: ShaderLocation.SIZE, + shaderLocation: this.attributeLocation.SIZE, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, @@ -167,7 +179,7 @@ export default class FillModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Shape', - shaderLocation: ShaderLocation.SHAPE, + shaderLocation: this.attributeLocation.SHAPE, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, diff --git a/packages/layers/src/point/models/fillImage.ts b/packages/layers/src/point/models/fillImage.ts index 94757d4aeca..412230139d6 100644 --- a/packages/layers/src/point/models/fillImage.ts +++ b/packages/layers/src/point/models/fillImage.ts @@ -1,16 +1,22 @@ import type { IAttribute, IElements, IEncodeFeature, IModel, ITexture2D } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; -import { getCullFace } from '@antv/l7-utils'; import BaseModel from '../../core/BaseModel'; import type { IPointLayerStyleOptions } from '../../core/interface'; import { SizeUnitType } from '../../core/interface'; import { PointFillTriangulation } from '../../core/triangulation'; -// static pointLayer shader - not support animate -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import pointFillFrag from '../shaders/fillImage/fillImage_frag.glsl'; import pointFillVert from '../shaders/fillImage/fillImage_vert.glsl'; export default class FillImageModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + SIZE: 9, + EXTRUDE: 10, + UV: 11, + }); + } + private meter2coord: number = 1; private texture: ITexture2D; private isMeter: boolean = false; @@ -29,13 +35,6 @@ export default class FillImageModel extends BaseModel { if (this.rendererService.getDirty()) { this.texture?.bind(); } - /** - * rotateFlag - * DEFAULT 1 - * MAPBOX 1 - * GAODE2.x -1 - * GAODE1.x -1 - */ const commonOptions = { u_textSize: [1024, this.iconService.canvasHeight || 128], @@ -73,10 +72,11 @@ export default class FillImageModel extends BaseModel { fragmentShader: pointFillFrag, triangulation: PointFillTriangulation, depth: { enable: false }, + defines: this.getDefines(), inject: this.getInject(), cull: { enable: true, - face: getCullFace(this.mapService.version), + face: gl.FRONT, }, }); return [model]; @@ -89,12 +89,15 @@ export default class FillImageModel extends BaseModel { // overwrite baseModel func protected registerBuiltinAttributes() { + // 注册 Position 属性 64 位地位部分,经纬度数据开启双精度,避免大于 20层级以上出现数据偏移 + this.registerPosition64LowAttribute(); + this.styleAttributeService.registerStyleAttribute({ name: 'uv', type: AttributeType.Attribute, descriptor: { name: 'a_Uv', - shaderLocation: ShaderLocation.UV, + shaderLocation: this.attributeLocation.UV, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, @@ -116,7 +119,7 @@ export default class FillImageModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Extrude', - shaderLocation: ShaderLocation.EXTRUDE, + shaderLocation: this.attributeLocation.EXTRUDE, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, @@ -144,7 +147,7 @@ export default class FillImageModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Size', - shaderLocation: ShaderLocation.SIZE, + shaderLocation: this.attributeLocation.SIZE, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, diff --git a/packages/layers/src/point/models/image.ts b/packages/layers/src/point/models/image.ts index 613c3a62560..f7d7b97bdc6 100644 --- a/packages/layers/src/point/models/image.ts +++ b/packages/layers/src/point/models/image.ts @@ -1,12 +1,19 @@ import type { IEncodeFeature, IModel, IModelUniform, ITexture2D } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import type { IPointLayerStyleOptions } from '../../core/interface'; import { PointImageTriangulation } from '../../core/triangulation'; import pointImageFrag from '../shaders/image/image_frag.glsl'; import pointImageVert from '../shaders/image/image_vert.glsl'; export default class ImageModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + SIZE: 9, + UV: 10, + }); + } + private texture: ITexture2D; public getUninforms(): IModelUniform { @@ -63,6 +70,7 @@ export default class ImageModel extends BaseModel { vertexShader: pointImageVert, fragmentShader: pointImageFrag, triangulation: PointImageTriangulation, + defines: this.getDefines(), inject: this.getInject(), depth: { enable: false }, primitive: gl.POINTS, @@ -71,13 +79,16 @@ export default class ImageModel extends BaseModel { } protected registerBuiltinAttributes() { + // 注册 Position 属性 64 位地位部分,经纬度数据开启双精度,避免大于 20层级以上出现数据偏移 + this.registerPosition64LowAttribute(); + // point layer size; this.styleAttributeService.registerStyleAttribute({ name: 'size', type: AttributeType.Attribute, descriptor: { name: 'a_Size', - shaderLocation: ShaderLocation.SIZE, + shaderLocation: this.attributeLocation.SIZE, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, @@ -98,7 +109,7 @@ export default class ImageModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Uv', - shaderLocation: ShaderLocation.UV, + shaderLocation: this.attributeLocation.UV, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, diff --git a/packages/layers/src/point/models/normal.ts b/packages/layers/src/point/models/normal.ts index 87cde43147d..b5d00a7ff37 100644 --- a/packages/layers/src/point/models/normal.ts +++ b/packages/layers/src/point/models/normal.ts @@ -1,7 +1,6 @@ import type { IEncodeFeature, IModel } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import type { IPointLayerStyleOptions } from '../../core/interface'; import normalFrag from '../shaders/normal/normal_frag.glsl'; import normalVert from '../shaders/normal/normal_vert.glsl'; @@ -16,6 +15,13 @@ export function PointTriangulation(feature: IEncodeFeature) { } export default class NormalModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + SIZE: 9, + }); + } + public getDefaultStyle(): Partial { return { blend: 'additive', @@ -45,6 +51,7 @@ export default class NormalModel extends BaseModel { vertexShader: normalVert, fragmentShader: normalFrag, triangulation: PointTriangulation, + defines: this.getDefines(), inject: this.getInject(), depth: { enable: false }, primitive: gl.POINTS, @@ -58,12 +65,15 @@ export default class NormalModel extends BaseModel { } protected registerBuiltinAttributes() { + // 注册 Position 属性 64 位地位部分,经纬度数据开启双精度,避免大于 20层级以上出现数据偏移 + this.registerPosition64LowAttribute(); + this.styleAttributeService.registerStyleAttribute({ name: 'size', type: AttributeType.Attribute, descriptor: { name: 'a_Size', - shaderLocation: ShaderLocation.SIZE, + shaderLocation: this.attributeLocation.SIZE, buffer: { usage: gl.DYNAMIC_DRAW, data: [], diff --git a/packages/layers/src/point/models/radar.ts b/packages/layers/src/point/models/radar.ts index aa557c4286c..2ebd0c71be0 100644 --- a/packages/layers/src/point/models/radar.ts +++ b/packages/layers/src/point/models/radar.ts @@ -11,12 +11,18 @@ import BaseModel from '../../core/BaseModel'; import type { IPointLayerStyleOptions } from '../../core/interface'; import { SizeUnitType } from '../../core/interface'; import { PointFillTriangulation } from '../../core/triangulation'; - -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import pointFillFrag from '../shaders/radar/radar_frag.glsl'; import pointFillVert from '../shaders/radar/radar_vert.glsl'; export default class RadarModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + SIZE: 9, + EXTRUDE: 10, + }); + } + protected getCommonUniformsInfo(): { uniformsArray: number[]; uniformsLength: number; @@ -64,6 +70,7 @@ export default class RadarModel extends BaseModel { vertexShader: pointFillVert, fragmentShader: pointFillFrag, triangulation: PointFillTriangulation, + defines: this.getDefines(), inject: this.getInject(), depth: { enable: false }, }); @@ -75,12 +82,15 @@ export default class RadarModel extends BaseModel { return [option.enable ? 0 : 1.0, option.speed || 1, option.rings || 3, 0]; } protected registerBuiltinAttributes() { + // 注册 Position 属性 64 位地位部分,经纬度数据开启双精度,避免大于 20层级以上出现数据偏移 + this.registerPosition64LowAttribute(); + this.styleAttributeService.registerStyleAttribute({ name: 'extrude', type: AttributeType.Attribute, descriptor: { name: 'a_Extrude', - shaderLocation: ShaderLocation.EXTRUDE, + shaderLocation: this.attributeLocation.EXTRUDE, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, @@ -106,7 +116,7 @@ export default class RadarModel extends BaseModel { name: 'size', type: AttributeType.Attribute, descriptor: { - shaderLocation: ShaderLocation.SIZE, + shaderLocation: this.attributeLocation.SIZE, name: 'a_Size', buffer: { // give the WebGL driver a hint that this buffer may change diff --git a/packages/layers/src/point/models/text.ts b/packages/layers/src/point/models/text.ts index 3007b21d39f..072cb0db072 100644 --- a/packages/layers/src/point/models/text.ts +++ b/packages/layers/src/point/models/text.ts @@ -8,7 +8,6 @@ import type { import { AttributeType, gl } from '@antv/l7-core'; import { boundsContains, calculateCentroid, lodashUtil, padBounds, rgb2arr } from '@antv/l7-utils'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import type { IPointLayerStyleOptions } from '../../core/interface'; import CollisionIndex from '../../utils/collision-index'; import type { IGlyphQuad } from '../../utils/symbol-layout'; @@ -73,6 +72,15 @@ export function TextTrianglation(feature: IEncodeFeature) { } export default class TextModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + SIZE: 9, + TEXT_OFFSETS: 10, + UV: 11, + }); + } + public glyphInfo: IEncodeFeature[]; public glyphInfoMap: { [key: string]: { @@ -154,6 +162,7 @@ export default class TextModel extends BaseModel { moduleName: 'pointText', vertexShader: textVert, fragmentShader: textFrag, + defines: this.getDefines(), inject: this.getInject(), triangulation: TextTrianglation.bind(this), depth: { enable: false }, @@ -215,11 +224,14 @@ export default class TextModel extends BaseModel { } protected registerBuiltinAttributes() { + // 注册 Position 属性 64 位地位部分,经纬度数据开启双精度,避免大于 20层级以上出现数据偏移 + this.registerPosition64LowAttribute(); + this.styleAttributeService.registerStyleAttribute({ name: 'textOffsets', type: AttributeType.Attribute, descriptor: { - shaderLocation: 10, + shaderLocation: this.attributeLocation.TEXT_OFFSETS, name: 'a_textOffsets', // 文字偏移量 buffer: { // give the WebGL driver a hint that this buffer may change @@ -233,12 +245,13 @@ export default class TextModel extends BaseModel { }, }, }); + this.styleAttributeService.registerStyleAttribute({ name: 'textUv', type: AttributeType.Attribute, descriptor: { name: 'a_tex', - shaderLocation: ShaderLocation.UV, + shaderLocation: this.attributeLocation.UV, buffer: { usage: gl.DYNAMIC_DRAW, data: [], @@ -250,13 +263,14 @@ export default class TextModel extends BaseModel { }, }, }); + // point layer size; this.styleAttributeService.registerStyleAttribute({ name: 'size', type: AttributeType.Attribute, descriptor: { name: 'a_Size', - shaderLocation: ShaderLocation.SIZE, + shaderLocation: this.attributeLocation.SIZE, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, @@ -398,12 +412,6 @@ export default class TextModel extends BaseModel { feature.centroid = calculateCentroid(feature.coordinates); - // 此时地图高德2.0 originCentroid == centroid - feature.originCentroid = - feature.version === 'GAODE2.x' - ? calculateCentroid(feature.originCoordinates) - : (feature.originCentroid = feature.centroid); - this.glyphInfoMap[id as number] = { shaping, glyphQuads, @@ -443,11 +451,7 @@ export default class TextModel extends BaseModel { const collisionIndex = new CollisionIndex(width, height); const filterData = this.glyphInfo.filter((feature: IEncodeFeature) => { const { shaping, id = 0 } = feature; - // const centroid = feature.centroid as [number, number]; - // const centroid = feature.originCentroid as [number, number]; - const centroid = ( - feature.version === 'GAODE2.x' ? feature.originCentroid : feature.centroid - ) as [number, number]; + const centroid = feature.centroid as [number, number]; const size = feature.size as number; const fontScale: number = size / 16; const pixels = this.mapService.lngLatToContainer(centroid); @@ -509,6 +513,7 @@ export default class TextModel extends BaseModel { vertexShader: textVert, fragmentShader: textFrag, triangulation: TextTrianglation.bind(this), + defines: this.getDefines(), inject: this.getInject(), depth: { enable: false }, }); diff --git a/packages/layers/src/point/shaders/billboard/billboard_point_vert.glsl b/packages/layers/src/point/shaders/billboard/billboard_point_vert.glsl index a0503b62142..25f0f54b0f7 100644 --- a/packages/layers/src/point/shaders/billboard/billboard_point_vert.glsl +++ b/packages/layers/src/point/shaders/billboard/billboard_point_vert.glsl @@ -1,7 +1,8 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in float a_Size; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_POSITION_64LOW) in vec2 a_Position64Low; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in float a_Size; layout(std140) uniform commonUniorm { vec4 u_stroke_color; @@ -19,18 +20,14 @@ out float v_innerRadius; #pragma include "project" void main() { v_color = vec4(a_Color.xyz, a_Color.w * opacity); - v_blur = 1.0 - max(2.0/a_Size, 0.05); + v_blur = 1.0 - max(2.0 / a_Size, 0.05); v_innerRadius = max((a_Size - u_stroke_width) / a_Size, 0.0); - + vec2 offset = project_pixel(u_offsets); - - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x - gl_Position = u_Mvp * vec4(a_Position.xy + offset, a_Position.z, 1.0); - } else { // else - vec4 project_pos = project_position(vec4(a_Position, 1.0)) + vec4(a_Size / 2.,-a_Size /2.,0.,0.); - gl_Position = project_common_position_to_clipspace(vec4(vec2(project_pos.xy+offset),project_pos.z,project_pos.w)); - } - + + vec4 project_pos = project_position(vec4(a_Position, 1.0), a_Position64Low); + gl_Position = project_common_position_to_clipspace(vec4(vec2(project_pos.xy+offset),project_pos.z,project_pos.w)); + gl_PointSize = a_Size * 2.0 * u_DevicePixelRatio; setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/point/shaders/earthExtrude/earthExtrude_vert.glsl b/packages/layers/src/point/shaders/earthExtrude/earthExtrude_vert.glsl index 65e94bbdb9a..be64a60ea63 100644 --- a/packages/layers/src/point/shaders/earthExtrude/earthExtrude_vert.glsl +++ b/packages/layers/src/point/shaders/earthExtrude/earthExtrude_vert.glsl @@ -5,13 +5,11 @@ precision highp float; #define diffuseRatio 0.3 #define specularRatio 0.2 - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in vec3 a_Size; -layout(location = 11) in vec3 a_Pos; -layout(location = 13) in vec3 a_Normal; - +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in vec3 a_Size; +layout(location = ATTRIBUTE_LOCATION_POS) in vec3 a_Pos; +layout(location = ATTRIBUTE_LOCATION_NORMAL) in vec3 a_Normal; layout(std140) uniform commonUniform { vec4 u_sourceColor; @@ -42,7 +40,7 @@ float getYRadian(float x, float z) { } else if(x > 0.0 && z <= 0.0){ return atan(-z/x) + pi/2.0; } else if(x <= 0.0 && z <= 0.0) { - return pi + atan(x/z); //atan(x/z) + + return pi + atan(x/z); //atan(x/z) + } else { return atan(z/-x) + pi*3.0/2.0; } @@ -62,15 +60,7 @@ void main() { vec3 offset = size; // 控制圆柱体的大小 - 从标准单位圆柱体进行偏移 if(u_heightfixed < 1.0) { // 圆柱体不固定高度 - - if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) { - // P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1 - offset = offset * pow(2.0, (19.0 - u_Zoom)); - } - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { - // P20_2 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减3 - offset = offset * pow(2.0, (19.0 - 3.0 - u_Zoom)); - } + // } else {// 圆柱体固定高度 ( 处理 mapbox ) if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { offset *= 4.0/pow(2.0, 21.0 - u_Zoom); @@ -98,7 +88,7 @@ void main() { } v_color.a *= u_opacity; - + // 在地球模式下,将原本垂直于 xy 平面的圆柱调整姿态到适应圆的角度 //旋转矩阵mx,创建绕x轴旋转矩阵 float r = sqrt(a_Pos.z*a_Pos.z + a_Pos.x*a_Pos.x); @@ -106,9 +96,9 @@ void main() { float xcos = cos(xRadian);//求解旋转角度余弦值 float xsin = sin(xRadian);//求解旋转角度正弦值 mat4 mx = mat4( - 1,0,0,0, - 0,xcos,-xsin,0, - 0,xsin,xcos,0, + 1,0,0,0, + 0,xcos,-xsin,0, + 0,xsin,xcos,0, 0,0,0,1); //旋转矩阵my,创建绕y轴旋转矩阵 @@ -116,13 +106,13 @@ void main() { float ycos = cos(yRadian);//求解旋转角度余弦值 float ysin = sin(yRadian);//求解旋转角度正弦值 mat4 my = mat4( - ycos,0,-ysin,0, - 0,1,0,0, - ysin,0,ycos,0, + ycos,0,-ysin,0, + 0,1,0,0, + ysin,0,ycos,0, 0,0,0,1); gl_Position = u_ViewProjectionMatrix * vec4(( my * mx * vec4(a_Position * a_Size, 1.0)).xyz + a_Pos, 1.0); - + setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/point/shaders/earthFill/earthFill_vert.glsl b/packages/layers/src/point/shaders/earthFill/earthFill_vert.glsl index 68fecdd3837..f312a0b4076 100644 --- a/packages/layers/src/point/shaders/earthFill/earthFill_vert.glsl +++ b/packages/layers/src/point/shaders/earthFill/earthFill_vert.glsl @@ -1,8 +1,8 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in float a_Size; -layout(location = 10) in float a_Shape; -layout(location = 11) in vec3 a_Extrude; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in float a_Size; +layout(location = ATTRIBUTE_LOCATION_SHAPE) in float a_Shape; +layout(location = ATTRIBUTE_LOCATION_EXTRUDE) in vec3 a_Extrude; layout(std140) uniform commonUniform { float u_additive; @@ -43,4 +43,4 @@ void main() { gl_Position = u_ViewProjectionMatrix * vec4(a_Position + extrude * newSize * 0.1 + vec3(u_offsets,0.0), 1.0); setPickingColor(a_PickingColor); -} \ No newline at end of file +} diff --git a/packages/layers/src/point/shaders/extrude/extrude_vert.glsl b/packages/layers/src/point/shaders/extrude/extrude_vert.glsl index bf62e62a267..e14653fc840 100644 --- a/packages/layers/src/point/shaders/extrude/extrude_vert.glsl +++ b/packages/layers/src/point/shaders/extrude/extrude_vert.glsl @@ -1,10 +1,10 @@ -#define pi 3.1415926535 +#define pi (3.1415926535) -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in vec3 a_Size; -layout(location = 11) in vec3 a_Extrude; -layout(location = 13) in vec3 a_Normal; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in vec3 a_Size; +layout(location = ATTRIBUTE_LOCATION_EXTRUDE) in vec4 a_Extrude; +layout(location = ATTRIBUTE_LOCATION_NORMAL) in vec3 a_Normal; layout(std140) uniform commonUniforms { float u_pickLight; @@ -25,46 +25,41 @@ out float v_lightWeight; #pragma include "picking" float getYRadian(float x, float z) { - if(x > 0.0 && z > 0.0) { - return atan(x/z); - } else if(x > 0.0 && z <= 0.0){ - return atan(-z/x) + pi/2.0; - } else if(x <= 0.0 && z <= 0.0) { - return pi + atan(x/z); //atan(x/z) + + if (x > 0.0 && z > 0.0) { + return atan(x / z); + } else if (x > 0.0 && z <= 0.0) { + return atan(-z / x) + pi / 2.0; + } else if (x <= 0.0 && z <= 0.0) { + return pi + atan(x / z); //atan(x/z) + } else { - return atan(z/-x) + pi*3.0/2.0; + return atan(z / -x) + pi * 3.0 / 2.0; } } float getXRadian(float y, float r) { - return atan(y/r); + return atan(y / r); } void main() { - - vec3 size = a_Size * a_Position; vec3 offset = size; // 控制圆柱体的大小 - 从标准单位圆柱体进行偏移 - if(u_heightfixed < 1.0) { // 圆柱体不固定高度 - - if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) { - // P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1 - offset = offset * pow(2.0, (19.0 - u_Zoom)); - } - if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { - // P20_2 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减3 - offset = offset * pow(2.0, (19.0 - 3.0 - u_Zoom)); - } - } else {// 圆柱体固定高度 ( 处理 mapbox ) - if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { - offset *= 4.0/pow(2.0, 21.0 - u_Zoom); + if (u_heightfixed < 1.0) { + // 圆柱体不固定高度 + } else { + // 圆柱体固定高度 ( 处理 mapbox ) + if ( + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET + ) { + offset *= 4.0 / pow(2.0, 21.0 - u_Zoom); } } - - vec4 project_pos = project_position(vec4(a_Extrude.xy, 0., 1.0)); + vec2 positions = a_Extrude.xy; + vec2 positions64Low = a_Extrude.zw; + vec4 project_pos = project_position(vec4(positions, 0.0, 1.0), positions64Low); // u_r 控制圆柱的生长 vec4 pos = vec4(project_pos.xy + offset.xy, offset.z * u_r, 1.0); @@ -72,7 +67,8 @@ void main() { // // 圆柱光照效果 float lightWeight = 1.0; - if(u_lightEnable > 0.0) { // 取消三元表达式,增强健壮性 + if (u_lightEnable > 0.0) { + // 取消三元表达式,增强健壮性 lightWeight = calc_lighting(pos); } @@ -80,20 +76,20 @@ void main() { v_color = a_Color; - // 设置圆柱的底色 - if(u_linearColor == 1.0) { // 使用渐变颜色 + // 设置圆柱的底色 + if (u_linearColor == 1.0) { + // 使用渐变颜色 v_color = mix(u_sourceColor, u_targetColor, a_Position.z); - v_color.a = v_color.a * opacity; + v_color.a = v_color.a * opacity; } else { v_color = vec4(a_Color.rgb * lightWeight, a_Color.w * opacity); } - if(u_opacitylinear > 0.0) { - v_color.a *= u_opacitylinear_dir > 0.0 ? (1.0 - a_Position.z): a_Position.z; + if (u_opacitylinear > 0.0) { + v_color.a *= u_opacitylinear_dir > 0.0 ? 1.0 - a_Position.z : a_Position.z; } - - gl_Position = project_common_position_to_clipspace_v2(pos); + gl_Position = project_common_position_to_clipspace(pos); setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/point/shaders/fill/fill_vert.glsl b/packages/layers/src/point/shaders/fill/fill_vert.glsl index 2c2bb37bc47..3e19ace461b 100644 --- a/packages/layers/src/point/shaders/fill/fill_vert.glsl +++ b/packages/layers/src/point/shaders/fill/fill_vert.glsl @@ -1,8 +1,9 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in float a_Size; -layout(location = 10) in float a_Shape; -layout(location = 11) in vec3 a_Extrude; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_POSITION_64LOW) in vec2 a_Position64Low; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in float a_Size; +layout(location = ATTRIBUTE_LOCATION_SHAPE) in float a_Shape; +layout(location = ATTRIBUTE_LOCATION_EXTRUDE) in vec3 a_Extrude; layout(std140) uniform commonUniforms { vec3 u_blur_height_fixed; @@ -11,7 +12,7 @@ layout(std140) uniform commonUniforms { float u_stroke_opacity; float u_size_unit; float u_time; - vec4 u_animate; + vec4 u_animate; }; out vec4 v_color; @@ -25,7 +26,7 @@ out float v_radius; void main() { // 透明度计算 - v_stroke = stroke; + v_stroke = stroke; vec3 extrude = a_Extrude; float shape_type = a_Shape; /* @@ -51,17 +52,14 @@ void main() { float antialiasblur = -max(2.0 / u_DevicePixelRatio / newSize, u_blur_height_fixed.x); vec2 offset = (extrude.xy * (newSize + u_stroke_width) + u_offsets); - vec3 aPosition = a_Position; offset = project_pixel(offset); offset = rotate_matrix(offset,rotation); - + // TODP: /abs(extrude.x) 是为了兼容地球模式 v_data = vec4(extrude.x/abs(extrude.x), extrude.y/abs(extrude.y), antialiasblur,shape_type); - - // vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0)); - vec4 project_pos = project_position(vec4(aPosition.xy, 0.0, 1.0)); + vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0), a_Position64Low); // gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, project_pixel(setPickingOrder(0.0)), 1.0)); float raisingHeight = u_blur_height_fixed.y; @@ -74,8 +72,8 @@ void main() { raisingHeight = u_blur_height_fixed.y * mapboxZoomScale; } } - - gl_Position = project_common_position_to_clipspace_v2(vec4(project_pos.xy + offset, raisingHeight, 1.0)); + + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, raisingHeight, 1.0)); setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/point/shaders/fillImage/fillImage_vert.glsl b/packages/layers/src/point/shaders/fillImage/fillImage_vert.glsl index 65d2d6f1abc..d260b19e486 100644 --- a/packages/layers/src/point/shaders/fillImage/fillImage_vert.glsl +++ b/packages/layers/src/point/shaders/fillImage/fillImage_vert.glsl @@ -1,13 +1,14 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in float a_Size; -layout(location = 11) in vec3 a_Extrude; -layout(location = 14) in vec2 a_Uv; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_POSITION_64LOW) in vec2 a_Position64Low; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in float a_Size; +layout(location = ATTRIBUTE_LOCATION_EXTRUDE) in vec3 a_Extrude; +layout(location = ATTRIBUTE_LOCATION_UV) in vec2 a_Uv; layout(std140) uniform commonUniform { vec2 u_textSize; - float u_heightfixed: 0.0; - float u_raisingHeight: 0.0; + float u_heightfixed; + float u_raisingHeight; float u_size_unit; }; @@ -15,43 +16,30 @@ out vec2 v_uv; out vec2 v_Iconuv; out float v_opacity; - #pragma include "projection" #pragma include "picking" #pragma include "rotation_2d" void main() { vec3 extrude = a_Extrude; - v_uv = (a_Extrude.xy + 1.0)/2.0; + v_uv = (a_Extrude.xy + 1.0) / 2.0; v_uv.y = 1.0 - v_uv.y; v_Iconuv = a_Uv; v_opacity = opacity; float newSize = a_Size; - if(u_size_unit == 1.0) { - newSize = newSize * u_PixelsPerMeter.z; + if (u_size_unit == 1.0) { + newSize = newSize * u_PixelsPerMeter.z; } - - // vec2 offset = (u_RotateMatrix * extrude.xy * (a_Size) + textrueOffsets); - vec2 offset = (extrude.xy * (newSize) + offsets); - offset = rotate_matrix(offset,rotation); + // vec2 offset = (u_RotateMatrix * extrude.xy * (a_Size) + textrueOffsets); + vec2 offset = extrude.xy * newSize + offsets; - vec3 aPosition = a_Position; + offset = rotate_matrix(offset, rotation); offset = project_pixel(offset); - vec4 project_pos = project_position(vec4(aPosition.xy, 0.0, 1.0)); - float raisingHeight = u_raisingHeight; - if(u_heightfixed < 1.0) { // height fixed - raisingHeight = project_pixel(u_raisingHeight); - } else { - if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { - float mapboxZoomScale = 4.0/pow(2.0, 21.0 - u_Zoom); - raisingHeight = u_raisingHeight * mapboxZoomScale; - } - } - - gl_Position = project_common_position_to_clipspace_v2(vec4(project_pos.xy + offset, 0.0, 1.0)); + vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0), a_Position64Low); + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0)); setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/point/shaders/image/image_vert.glsl b/packages/layers/src/point/shaders/image/image_vert.glsl index 5b00b12213b..adeab3a5e18 100644 --- a/packages/layers/src/point/shaders/image/image_vert.glsl +++ b/packages/layers/src/point/shaders/image/image_vert.glsl @@ -1,7 +1,8 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in float a_Size; -layout(location = 14) in vec2 a_Uv; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_POSITION_64LOW) in vec2 a_Position64Low; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in float a_Size; +layout(location = ATTRIBUTE_LOCATION_UV) in vec2 a_Uv; layout(std140) uniform commonUniforms { vec2 u_textSize; @@ -17,27 +18,29 @@ out float v_opacity; #pragma include "picking" void main() { - // cal style mapping - 数据纹理映射部分的计算 v_color = a_Color; v_opacity = opacity; v_uv = a_Uv; - vec4 project_pos = project_position(vec4(a_Position, 1.0)); - + vec4 project_pos = project_position(vec4(a_Position, 1.0), a_Position64Low); + vec2 offset = project_pixel(offsets); float raisingHeight = u_raisingHeight; - if(u_heightfixed < 1.0) { // false + if (u_heightfixed < 1.0) { + // false raisingHeight = project_pixel(u_raisingHeight); } else { - if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { - float mapboxZoomScale = 4.0/pow(2.0, 21.0 - u_Zoom); + if ( + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET + ) { + float mapboxZoomScale = 4.0 / pow(2.0, 21.0 - u_Zoom); raisingHeight = u_raisingHeight * mapboxZoomScale; } } - - gl_Position = project_common_position_to_clipspace_v2(vec4(project_pos.xy + offset, raisingHeight, 1.0)); + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, raisingHeight, 1.0)); gl_PointSize = a_Size * 2.0 * u_DevicePixelRatio; setPickingColor(a_PickingColor); diff --git a/packages/layers/src/point/shaders/normal/normal_vert.glsl b/packages/layers/src/point/shaders/normal/normal_vert.glsl index e7a784ed18d..6a0e617ed38 100644 --- a/packages/layers/src/point/shaders/normal/normal_vert.glsl +++ b/packages/layers/src/point/shaders/normal/normal_vert.glsl @@ -1,6 +1,7 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in float a_Size; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_POSITION_64LOW) in vec2 a_Position64Low; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in float a_Size; layout(std140) uniform u_Common { float u_size_scale; @@ -14,12 +15,8 @@ out vec4 v_color; void main() { v_color = vec4(a_Color.xyz, a_Color.w * opacity); - if (u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x - gl_Position = u_Mvp * vec4(a_Position, 1.0); - } else { - vec4 project_pos = project_position(vec4(a_Position, 1.0)) + vec4(a_Size / 2., -a_Size /2., 0., 0.); - gl_Position = project_common_position_to_clipspace(project_pos); - } + vec4 project_pos = project_position(vec4(a_Position, 1.0), a_Position64Low); + gl_Position = project_common_position_to_clipspace(project_pos); - gl_PointSize = a_Size * u_size_scale * 2.0 * u_DevicePixelRatio; + gl_PointSize = a_Size * u_size_scale * 2.0 * u_DevicePixelRatio; } diff --git a/packages/layers/src/point/shaders/radar/radar_vert.glsl b/packages/layers/src/point/shaders/radar/radar_vert.glsl index 3c9ab56e499..dd390024b48 100644 --- a/packages/layers/src/point/shaders/radar/radar_vert.glsl +++ b/packages/layers/src/point/shaders/radar/radar_vert.glsl @@ -1,7 +1,8 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in float a_Size; -layout(location = 11) in vec3 a_Extrude; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_POSITION_64LOW) in vec2 a_Position64Low; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in float a_Size; +layout(location = ATTRIBUTE_LOCATION_EXTRUDE) in vec3 a_Extrude; layout(std140) uniform commonUniorm { float u_additive; @@ -22,8 +23,8 @@ void main() { float newSize = setPickingSize(a_Size); float time = u_time * u_speed; - mat2 rotateMatrix = mat2( - cos(time), sin(time), + mat2 rotateMatrix = mat2( + cos(time), sin(time), -sin(time), cos(time) ); v_extrude = rotateMatrix * a_Extrude.xy; @@ -40,14 +41,13 @@ void main() { v_radius = newSize; vec2 offset = (a_Extrude.xy * (newSize)); - vec3 aPosition = a_Position; - + offset = project_pixel(offset); - + v_data = vec4(a_Extrude.x, a_Extrude.y, antialiasblur, -1.0); - vec4 project_pos = project_position(vec4(aPosition.xy, 0.0, 1.0)); - gl_Position = project_common_position_to_clipspace_v2(vec4(project_pos.xy + offset, project_pixel(setPickingOrder(0.0)), 1.0)); + vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0), a_Position64Low); + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, project_pixel(setPickingOrder(0.0)), 1.0)); setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/point/shaders/text/text_vert.glsl b/packages/layers/src/point/shaders/text/text_vert.glsl index 453fa2a7e34..5a51d90ff69 100644 --- a/packages/layers/src/point/shaders/text/text_vert.glsl +++ b/packages/layers/src/point/shaders/text/text_vert.glsl @@ -2,11 +2,12 @@ #define EDGE_GAMMA 0.105 #define FONT_SIZE 24.0 -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in float a_Size; -layout(location = 10) in vec2 a_textOffsets; -layout(location = 14) in vec2 a_tex; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_POSITION_64LOW) in vec2 a_Position64Low; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in float a_Size; +layout(location = ATTRIBUTE_LOCATION_TEXT_OFFSETS) in vec2 a_textOffsets; +layout(location = ATTRIBUTE_LOCATION_UV) in vec2 a_tex; layout(std140) uniform commonUniforms { vec4 u_stroke_color : [0.0, 0.0, 0.0, 0.0]; @@ -29,7 +30,7 @@ out float v_fontScale; void main() { // cal style mapping - 数据纹理映射部分的计算 - + v_uv = a_tex / u_sdf_map_size; @@ -41,11 +42,11 @@ void main() { float fontScale = a_Size / FONT_SIZE; v_fontScale = fontScale; - vec4 project_pos = project_position(vec4(a_Position, 1.0)); + vec4 project_pos = project_position(vec4(a_Position, 1.0), a_Position64Low); // vec4 projected_position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); vec2 offset = rotate_matrix(a_textOffsets,rotation); - + // gl_Position = vec4(projected_position.xy / projected_position.w + rotation_matrix * a_textOffsets * fontScale / u_ViewportSize * 2.0 * u_DevicePixelRatio, 0.0, 1.0); float raiseHeight = u_raisingHeight; @@ -54,7 +55,7 @@ void main() { raiseHeight = u_raisingHeight * mapboxZoomScale; } - vec4 projected_position = project_common_position_to_clipspace_v2(vec4(project_pos.xyz + vec3(0.0, 0.0, raiseHeight), 1.0)); + vec4 projected_position = project_common_position_to_clipspace(vec4(project_pos.xyz + vec3(0.0, 0.0, raiseHeight), 1.0)); gl_Position = vec4( projected_position.xy / projected_position.w + offset * fontScale / u_ViewportSize * 2.0 * u_DevicePixelRatio, 0.0, 1.0); diff --git a/packages/layers/src/polygon/models/extrude.ts b/packages/layers/src/polygon/models/extrude.ts index 832d2a8217b..3014ff333c8 100644 --- a/packages/layers/src/polygon/models/extrude.ts +++ b/packages/layers/src/polygon/models/extrude.ts @@ -4,20 +4,24 @@ import { rgb2arr } from '@antv/l7-utils'; import BaseModel from '../../core/BaseModel'; import type { IPolygonLayerStyleOptions } from '../../core/interface'; import { PolygonExtrudeTriangulation } from '../../core/triangulation'; +import { loadImage } from '../../utils/load-image'; import polygonExtrudeFrag from '../shaders/extrude/polygon_extrude_frag.glsl'; +import polygonExtrudePickLightFrag from '../shaders/extrude/polygon_extrude_picklight_frag.glsl'; +import polygonExtrudePickLightVert from '../shaders/extrude/polygon_extrude_picklight_vert.glsl'; import polygonExtrudeVert from '../shaders/extrude/polygon_extrude_vert.glsl'; -// extrude import polygonExtrudeTexFrag from '../shaders/extrude/polygon_extrudetex_frag.glsl'; -// texture import polygonExtrudeTexVert from '../shaders/extrude/polygon_extrudetex_vert.glsl'; -// extrude picking - -import { ShaderLocation } from '../../core/CommonStyleAttribute'; -import { loadImage } from '../../utils/load-image'; -import polygonExtrudePickLightFrag from '../shaders/extrude/polygon_extrude_picklight_frag.glsl'; -import polygonExtrudePickLightVert from '../shaders/extrude/polygon_extrude_picklight_vert.glsl'; export default class ExtrudeModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + SIZE: 9, + NORMAL: 10, + UV: 11, + }); + } + protected texture: ITexture2D; public getUninforms() { const commoninfo = this.getCommonUniformsInfo(); @@ -84,6 +88,7 @@ export default class ExtrudeModel extends BaseModel { vertexShader: vert, fragmentShader: frag, depth: { enable: true }, + defines: this.getDefines(), inject: this.getInject(), triangulation: PolygonExtrudeTriangulation, }); @@ -120,34 +125,19 @@ export default class ExtrudeModel extends BaseModel { } protected registerBuiltinAttributes() { - const bbox = this.layer.getSource().extent; - let bounds = bbox; - const layerCenter = this.layer.coordCenter || this.layer.getSource().center; - let lngLen = bounds[2] - bounds[0]; - let latLen = bounds[3] - bounds[1]; + const bounds = this.layer.getSource().extent; + const lngLen = bounds[2] - bounds[0]; + const latLen = bounds[3] - bounds[1]; - if (this.mapService.version === 'GAODE2.x') { - // @ts-ignore - const [minX, minY] = this.mapService.coordToAMap2RelativeCoordinates( - [bbox[0], bbox[1]], - layerCenter, - ); - // @ts-ignore - const [maxX, maxY] = this.mapService.coordToAMap2RelativeCoordinates( - [bbox[2], bbox[3]], - layerCenter, - ); - lngLen = maxX - minX; - latLen = maxY - minY; - bounds = [minX, minY, maxX, maxY]; - } + // 注册 Position 属性 64 位地位部分,经纬度数据开启双精度,避免大于 22 层级以上出现数据偏移 + this.registerPosition64LowAttribute(); this.styleAttributeService.registerStyleAttribute({ name: 'uvs', type: AttributeType.Attribute, descriptor: { name: 'a_uvs', - shaderLocation: ShaderLocation.UV, + shaderLocation: this.attributeLocation.UV, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.STATIC_DRAW, @@ -168,7 +158,7 @@ export default class ExtrudeModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Normal', - shaderLocation: ShaderLocation.NORMAL, + shaderLocation: this.attributeLocation.NORMAL, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.STATIC_DRAW, @@ -193,7 +183,7 @@ export default class ExtrudeModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Size', - shaderLocation: ShaderLocation.SIZE, + shaderLocation: this.attributeLocation.SIZE, buffer: { usage: gl.DYNAMIC_DRAW, data: [], diff --git a/packages/layers/src/polygon/models/extrusion.ts b/packages/layers/src/polygon/models/extrusion.ts index 52f4edca2a9..abfc33f750c 100644 --- a/packages/layers/src/polygon/models/extrusion.ts +++ b/packages/layers/src/polygon/models/extrusion.ts @@ -1,13 +1,22 @@ import type { IEncodeFeature, IModel, ITexture2D } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import { PolygonExtrudeTriangulation } from '../../core/triangulation'; import polygonExtrudeFrag from '../shaders/extrusion/polygon_extrusion_frag.glsl'; import polygonExtrudeVert from '../shaders/extrusion/polygon_extrusion_vert.glsl'; export default class ExtrusionModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + SIZE: 9, + NORMAL: 10, + EXTRUSION_BASE: 11, + }); + } + protected texture: ITexture2D; + public getUninforms() { const commoninfo = this.getCommonUniformsInfo(); const attributeInfo = this.getUniformsBufferInfo(this.getStyleAttribute()); @@ -39,6 +48,7 @@ export default class ExtrusionModel extends BaseModel { moduleName: type, vertexShader: vert, fragmentShader: frag, + defines: this.getDefines(), inject: this.getInject(), triangulation: PolygonExtrudeTriangulation, depth: { enable: true }, @@ -59,12 +69,15 @@ export default class ExtrusionModel extends BaseModel { } protected registerBuiltinAttributes() { + // 注册 Position 属性 64 位地位部分,经纬度数据开启双精度,避免大于 22 层级以上出现数据偏移 + this.registerPosition64LowAttribute(); + this.styleAttributeService.registerStyleAttribute({ name: 'normal', type: AttributeType.Attribute, descriptor: { name: 'a_Normal', - shaderLocation: ShaderLocation.NORMAL, + shaderLocation: this.attributeLocation.NORMAL, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.STATIC_DRAW, @@ -89,7 +102,7 @@ export default class ExtrusionModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Size', - shaderLocation: ShaderLocation.SIZE, + shaderLocation: this.attributeLocation.SIZE, buffer: { usage: gl.DYNAMIC_DRAW, data: [], @@ -102,5 +115,24 @@ export default class ExtrusionModel extends BaseModel { }, }, }); + + this.styleAttributeService.registerStyleAttribute({ + name: 'extrusionBase', + type: AttributeType.Attribute, + descriptor: { + name: 'a_ExtrusionBase', + shaderLocation: this.attributeLocation.EXTRUSION_BASE, + buffer: { + usage: gl.STATIC_DRAW, + data: [], + type: gl.FLOAT, + }, + size: 1, + update: (feature: IEncodeFeature) => { + const { extrusionBase: op = 0 } = feature; + return [op]; + }, + }, + }); } } diff --git a/packages/layers/src/polygon/models/fill.ts b/packages/layers/src/polygon/models/fill.ts index 277801161bd..2c47248aa53 100644 --- a/packages/layers/src/polygon/models/fill.ts +++ b/packages/layers/src/polygon/models/fill.ts @@ -1,7 +1,6 @@ import type { IEncodeFeature, IModel, Triangulation } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import type { IPolygonLayerStyleOptions } from '../../core/interface'; import { polygonTriangulation, polygonTriangulationWithCenter } from '../../core/triangulation'; import polygon_frag from '../shaders/fill/fill_frag.glsl'; @@ -9,6 +8,13 @@ import polygon_linear_frag from '../shaders/fill/fill_linear_frag.glsl'; import polygon_linear_vert from '../shaders/fill/fill_linear_vert.glsl'; import polygon_vert from '../shaders/fill/fill_vert.glsl'; export default class FillModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + LINEAR: 9, + }); + } + public getUninforms() { const commoninfo = this.getCommonUniformsInfo(); const attributeInfo = this.getUniformsBufferInfo(this.getStyleAttribute()); @@ -53,6 +59,7 @@ export default class FillModel extends BaseModel { moduleName: type, vertexShader: vert, fragmentShader: frag, + defines: this.getDefines(), inject: this.getInject(), triangulation, primitive: gl.TRIANGLES, @@ -62,12 +69,16 @@ export default class FillModel extends BaseModel { } protected registerBuiltinAttributes() { + // 注册 Position 属性 64 位地位部分,经纬度数据开启双精度,避免大于 22 层级以上出现数据偏移 + this.registerPosition64LowAttribute(); + const { opacityLinear = { enable: false, dir: 'in', }, } = this.layer.getLayerConfig() as IPolygonLayerStyleOptions; + if (opacityLinear.enable) { this.styleAttributeService.registerStyleAttribute({ name: 'linear', @@ -75,7 +86,7 @@ export default class FillModel extends BaseModel { descriptor: { name: 'a_linear', - shaderLocation: ShaderLocation.LINEAR, + shaderLocation: this.attributeLocation.LINEAR, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.STATIC_DRAW, diff --git a/packages/layers/src/polygon/models/ocean.ts b/packages/layers/src/polygon/models/ocean.ts index 069c3659138..4291c47092b 100644 --- a/packages/layers/src/polygon/models/ocean.ts +++ b/packages/layers/src/polygon/models/ocean.ts @@ -2,12 +2,18 @@ import type { IEncodeFeature, IModel, IModelUniform, ITexture2D } from '@antv/l7 import { AttributeType, gl } from '@antv/l7-core'; import { rgb2arr } from '@antv/l7-utils'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import type { IPolygonLayerStyleOptions } from '../../core/interface'; import { polygonTriangulation } from '../../core/triangulation'; import ocean_frag from '../shaders/ocean/ocean_frag.glsl'; import ocean_vert from '../shaders/ocean/ocean_vert.glsl'; export default class OceanModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + UV: 9, + }); + } + private texture1: ITexture2D; private texture2: ITexture2D; private texture3: ITexture2D; @@ -59,6 +65,7 @@ export default class OceanModel extends BaseModel { moduleName: 'polygonOcean', vertexShader: ocean_vert, fragmentShader: ocean_frag, + defines: this.getDefines(), inject: this.getInject(), triangulation: polygonTriangulation, primitive: gl.TRIANGLES, @@ -84,7 +91,7 @@ export default class OceanModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_uv', - shaderLocation: ShaderLocation.UV, + shaderLocation: this.attributeLocation.UV, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.STATIC_DRAW, @@ -92,15 +99,8 @@ export default class OceanModel extends BaseModel { type: gl.FLOAT, }, size: 2, - update: ( - feature: IEncodeFeature, - featureIdx: number, - vertex: number[], - attributeIdx: number, - ) => { - const v = - feature.version === 'GAODE2.x' ? feature.originCoordinates[0][attributeIdx] : vertex; - const [lng, lat] = v; + update: (feature: IEncodeFeature, featureIdx: number, vertex: number[]) => { + const [lng, lat] = vertex; return [(lng - minLng) / lngLen, (lat - minLat) / latLen]; }, }, diff --git a/packages/layers/src/polygon/models/water.ts b/packages/layers/src/polygon/models/water.ts index 149edd3f0b2..2d85c2901d4 100644 --- a/packages/layers/src/polygon/models/water.ts +++ b/packages/layers/src/polygon/models/water.ts @@ -1,12 +1,19 @@ import type { IEncodeFeature, IModel, IModelUniform, ITexture2D } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import type { IPolygonLayerStyleOptions } from '../../core/interface'; import { polygonTriangulation } from '../../core/triangulation'; import water_frag from '../shaders/water/polygon_water_frag.glsl'; import water_vert from '../shaders/water/polygon_water_vert.glsl'; + export default class WaterModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + UV: 9, + }); + } + private texture: ITexture2D; public getUninforms() { const commoninfo = this.getCommonUniformsInfo(); @@ -54,6 +61,7 @@ export default class WaterModel extends BaseModel { vertexShader: water_vert, fragmentShader: water_frag, triangulation: polygonTriangulation, + defines: this.getDefines(), inject: this.getInject(), primitive: gl.TRIANGLES, depth: { enable: false }, @@ -78,7 +86,7 @@ export default class WaterModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_uv', - shaderLocation: ShaderLocation.UV, + shaderLocation: this.attributeLocation.UV, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.STATIC_DRAW, @@ -86,15 +94,8 @@ export default class WaterModel extends BaseModel { type: gl.FLOAT, }, size: 2, - update: ( - feature: IEncodeFeature, - featureIdx: number, - vertex: number[], - attributeIdx: number, - ) => { - const v = - feature.version === 'GAODE2.x' ? feature.originCoordinates[0][attributeIdx] : vertex; - const [lng, lat] = v; + update: (feature: IEncodeFeature, featureIdx: number, vertex: number[]) => { + const [lng, lat] = vertex; return [(lng - minLng) / lngLen, (lat - minLat) / latLen]; }, }, diff --git a/packages/layers/src/polygon/shaders/extrude/polygon_extrude_picklight_vert.glsl b/packages/layers/src/polygon/shaders/extrude/polygon_extrude_picklight_vert.glsl index 84ad306a79a..a17be1dc88d 100644 --- a/packages/layers/src/polygon/shaders/extrude/polygon_extrude_picklight_vert.glsl +++ b/packages/layers/src/polygon/shaders/extrude/polygon_extrude_picklight_vert.glsl @@ -1,9 +1,9 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in float a_Size; -layout(location = 13) in vec3 a_Normal; -layout(location = 14) in vec3 a_uvs; - +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_POSITION_64LOW) in vec2 a_Position64Low; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in float a_Size; +layout(location = ATTRIBUTE_LOCATION_NORMAL) in vec3 a_Normal; +layout(location = ATTRIBUTE_LOCATION_UV) in vec3 a_uvs; layout(std140) uniform commonUniforms { vec4 u_sourceColor; @@ -24,26 +24,28 @@ out vec2 v_texture_data; #pragma include "picking" void main() { - - v_uvs = a_uvs; // cal style mapping - 数据纹理映射部分的计算 vec4 pos = vec4(a_Position.xy, a_Position.z * a_Size, 1.0); - vec4 project_pos = project_position(pos); + vec4 project_pos = project_position(pos, a_Position64Low); - if(u_heightfixed > 0.0) { // 判断几何体是否固定高度 + if (u_heightfixed > 0.0) { + // 判断几何体是否固定高度 project_pos.z = a_Position.z * a_Size; project_pos.z += u_raisingHeight; - if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { - float mapboxZoomScale = 4.0/pow(2.0, 21.0 - u_Zoom); + if ( + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET + ) { + float mapboxZoomScale = 4.0 / pow(2.0, 21.0 - u_Zoom); project_pos.z *= mapboxZoomScale; project_pos.z += u_raisingHeight * mapboxZoomScale; } } - gl_Position = project_common_position_to_clipspace_v2(vec4(project_pos.xyz, 1.0)); - float lightWeight = calc_lighting(pos); - v_texture_data = vec2(a_Position.z,lightWeight); + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); + float lightWeight = calc_lighting(project_pos); + v_texture_data = vec2(a_Position.z, lightWeight); v_Color = vec4(a_Color.rgb * lightWeight, a_Color.w * opacity); diff --git a/packages/layers/src/polygon/shaders/extrude/polygon_extrude_vert.glsl b/packages/layers/src/polygon/shaders/extrude/polygon_extrude_vert.glsl index a341760cd93..4342f6e6ad7 100644 --- a/packages/layers/src/polygon/shaders/extrude/polygon_extrude_vert.glsl +++ b/packages/layers/src/polygon/shaders/extrude/polygon_extrude_vert.glsl @@ -1,8 +1,9 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in float a_Size; -layout(location = 13) in vec3 a_Normal; -layout(location = 14) in vec3 a_uvs; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_POSITION_64LOW) in vec2 a_Position64Low; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in float a_Size; +layout(location = ATTRIBUTE_LOCATION_NORMAL) in vec3 a_Normal; +layout(location = ATTRIBUTE_LOCATION_UV) in vec3 a_uvs; layout(std140) uniform commonUniforms { vec4 u_sourceColor; @@ -21,39 +22,41 @@ out vec4 v_Color; #pragma include "picking" void main() { - -float isSide = a_Position.z; - float topU = a_uvs[0]; - float topV = 1.0 - a_uvs[1]; - float sidey = a_uvs[2]; + float isSide = a_Position.z; + float topU = a_uvs[0]; + float topV = 1.0 - a_uvs[1]; + float sidey = a_uvs[2]; vec4 pos = vec4(a_Position.xy, a_Position.z * a_Size, 1.0); - float lightWeight = calc_lighting(pos); - vec4 project_pos = project_position(pos); + vec4 project_pos = project_position(pos, a_Position64Low); + float lightWeight = calc_lighting(project_pos); - if(u_heightfixed > 0.0) { // 判断几何体是否固定高度 + if (u_heightfixed > 0.0) { + // 判断几何体是否固定高度 project_pos.z = a_Position.z * a_Size; project_pos.z += u_raisingHeight; - if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { - float mapboxZoomScale = 4.0/pow(2.0, 21.0 - u_Zoom); + if ( + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET + ) { + float mapboxZoomScale = 4.0 / pow(2.0, 21.0 - u_Zoom); project_pos.z *= mapboxZoomScale; project_pos.z += u_raisingHeight * mapboxZoomScale; } } - - gl_Position = project_common_position_to_clipspace_v2(vec4(project_pos.xyz, 1.0)); + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); // Tip: 部分机型 GPU 计算精度兼容 - if(isSide < 0.999) { + if (isSide < 0.999) { // side face // if(u_sidesurface < 1.0) { // discard; // } - if(u_linearColor == 1.0) { + if (u_linearColor == 1.0) { vec4 linearColor = mix(u_targetColor, u_sourceColor, sidey); linearColor.rgb *= lightWeight; v_Color = linearColor; @@ -67,6 +70,5 @@ float isSide = a_Position.z; v_Color = vec4(v_Color.rgb * lightWeight, v_Color.w * opacity); - setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/polygon/shaders/extrude/polygon_extrudetex_vert.glsl b/packages/layers/src/polygon/shaders/extrude/polygon_extrudetex_vert.glsl index 2717736fba7..8f1350b7a68 100644 --- a/packages/layers/src/polygon/shaders/extrude/polygon_extrudetex_vert.glsl +++ b/packages/layers/src/polygon/shaders/extrude/polygon_extrudetex_vert.glsl @@ -1,9 +1,9 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in float a_Size; -layout(location = 13) in vec3 a_Normal; -layout(location = 14) in vec3 a_uvs; - +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_POSITION_64LOW) in vec2 a_Position64Low; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in float a_Size; +layout(location = ATTRIBUTE_LOCATION_NORMAL) in vec3 a_Normal; +layout(location = ATTRIBUTE_LOCATION_UV) in vec3 a_uvs; layout(std140) uniform commonUniforms { vec4 u_sourceColor; @@ -24,31 +24,31 @@ out vec2 v_texture_data; #pragma include "picking" void main() { - vec4 pos = vec4(a_Position.xy, a_Position.z * a_Size, 1.0); - float lightWeight = calc_lighting(pos); - vec4 project_pos = project_position(pos); + vec4 project_pos = project_position(pos, a_Position64Low); + float lightWeight = calc_lighting(project_pos); v_uvs = a_uvs; v_Color = a_Color; v_Color.a *= opacity; - + v_texture_data = vec2(a_Position.z, lightWeight); - if(u_heightfixed > 0.0) { // 判断几何体是否固定高度 + if (u_heightfixed > 0.0) { + // 判断几何体是否固定高度 project_pos.z = a_Position.z * a_Size; project_pos.z += u_raisingHeight; - if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { - float mapboxZoomScale = 4.0/pow(2.0, 21.0 - u_Zoom); + if ( + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET + ) { + float mapboxZoomScale = 4.0 / pow(2.0, 21.0 - u_Zoom); project_pos.z *= mapboxZoomScale; project_pos.z += u_raisingHeight * mapboxZoomScale; } } - - gl_Position = project_common_position_to_clipspace_v2(vec4(project_pos.xyz, 1.0)); - - + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/polygon/shaders/extrusion/polygon_extrusion_vert.glsl b/packages/layers/src/polygon/shaders/extrusion/polygon_extrusion_vert.glsl index b5b8d506c00..5dcb7e8bb70 100644 --- a/packages/layers/src/polygon/shaders/extrusion/polygon_extrusion_vert.glsl +++ b/packages/layers/src/polygon/shaders/extrusion/polygon_extrusion_vert.glsl @@ -1,7 +1,8 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 9) in float a_Size; -layout(location = 13) in vec3 a_Normal; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_POSITION_64LOW) in vec2 a_Position64Low; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_SIZE) in float a_Size; +layout(location = ATTRIBUTE_LOCATION_NORMAL) in vec3 a_Normal; out vec4 v_Color; @@ -10,15 +11,14 @@ out vec4 v_Color; #pragma include "picking" void main() { - vec4 pos = vec4(a_Position.xy, a_Position.z * a_Size + (1.0 - a_Position.z) * extrusionBase, 1.0); - vec4 project_pos = project_position(pos); - float lightWeight = calc_lighting(project_pos); + vec4 project_pos = project_position(pos, a_Position64Low); + float lightWeight = calc_lighting(project_pos); v_Color = a_Color; v_Color = vec4(v_Color.rgb * lightWeight, v_Color.w * opacity); - gl_Position = project_common_position_to_clipspace_v2(vec4(project_pos.xyz, 1.0)); + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/polygon/shaders/fill/fill_linear_vert.glsl b/packages/layers/src/polygon/shaders/fill/fill_linear_vert.glsl index 969698a6e0e..8b57b36d96a 100644 --- a/packages/layers/src/polygon/shaders/fill/fill_linear_vert.glsl +++ b/packages/layers/src/polygon/shaders/fill/fill_linear_vert.glsl @@ -1,6 +1,7 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 15) in vec3 a_linear; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_POSITION_64LOW) in vec2 a_Position64Low; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_LINEAR) in vec3 a_linear; layout(std140) uniform commonUniforms { float u_raisingHeight; @@ -21,7 +22,7 @@ void main() { v_pos = a_Position.xy; } v_color = vec4(a_Color.xyz, a_Color.w * opacity); - vec4 project_pos = project_position(vec4(a_Position, 1.0)); + vec4 project_pos = project_position(vec4(a_Position, 1.0), a_Position64Low); project_pos.z += u_raisingHeight; if (u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { @@ -30,6 +31,6 @@ void main() { project_pos.z += u_raisingHeight * mapboxZoomScale; } - gl_Position = project_common_position_to_clipspace_v2(vec4(project_pos.xyz, 1.0)); + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); setPickingColor(a_PickingColor); -} \ No newline at end of file +} diff --git a/packages/layers/src/polygon/shaders/fill/fill_vert.glsl b/packages/layers/src/polygon/shaders/fill/fill_vert.glsl index a1117dc6964..65c0343d037 100644 --- a/packages/layers/src/polygon/shaders/fill/fill_vert.glsl +++ b/packages/layers/src/polygon/shaders/fill/fill_vert.glsl @@ -1,36 +1,34 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_POSITION_64LOW) in vec2 a_Position64Low; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; layout(std140) uniform commonUniforms { float u_raisingHeight; }; - out vec4 v_color; - #pragma include "projection" #pragma include "picking" void main() { // cal style mapping - 数据纹理映射部分的计算 - // cal style mapping - 数据纹理映射部分的计算 - v_color = vec4(a_Color.xyz, a_Color.w * opacity); - vec4 project_pos = project_position(vec4(a_Position, 1.0)); - // gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); + vec4 project_pos = project_position(vec4(a_Position, 1.0), a_Position64Low); project_pos.z += u_raisingHeight; - if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) { - float mapboxZoomScale = 4.0/pow(2.0, 21.0 - u_Zoom); + if ( + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || + u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET + ) { + float mapboxZoomScale = 4.0 / pow(2.0, 21.0 - u_Zoom); project_pos.z *= mapboxZoomScale; project_pos.z += u_raisingHeight * mapboxZoomScale; } - - gl_Position = project_common_position_to_clipspace_v2(vec4(project_pos.xyz, 1.0)); + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); setPickingColor(a_PickingColor); } diff --git a/packages/layers/src/polygon/shaders/ocean/ocean_vert.glsl b/packages/layers/src/polygon/shaders/ocean/ocean_vert.glsl index 854bdbe3ced..33244f320f0 100644 --- a/packages/layers/src/polygon/shaders/ocean/ocean_vert.glsl +++ b/packages/layers/src/polygon/shaders/ocean/ocean_vert.glsl @@ -1,5 +1,5 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 14) in vec2 a_uv; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_UV) in vec2 a_uv; layout(std140) uniform commonUniforms { vec4 u_watercolor; @@ -7,7 +7,6 @@ layout(std140) uniform commonUniforms { float u_time; }; - out vec2 v_uv; out float v_opacity; @@ -17,6 +16,6 @@ void main() { v_uv = a_uv; v_opacity = opacity; vec4 project_pos = project_position(vec4(a_Position, 1.0)); - gl_Position = project_common_position_to_clipspace_v2(vec4(project_pos.xyz, 1.0)); + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); } diff --git a/packages/layers/src/polygon/shaders/water/polygon_water_vert.glsl b/packages/layers/src/polygon/shaders/water/polygon_water_vert.glsl index 03fc492d3ca..c9c6d160889 100644 --- a/packages/layers/src/polygon/shaders/water/polygon_water_vert.glsl +++ b/packages/layers/src/polygon/shaders/water/polygon_water_vert.glsl @@ -1,6 +1,7 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 14) in vec2 a_uv; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_COLOR) in vec4 a_Color; +layout(location = ATTRIBUTE_LOCATION_UV) in vec2 a_uv; + layout(std140) uniform commonUniforms { float u_speed; float u_time; @@ -8,7 +9,6 @@ layout(std140) uniform commonUniforms { out vec4 v_Color; out vec2 v_uv; - #pragma include "projection" void main() { @@ -17,6 +17,6 @@ void main() { v_Color.a *= opacity; vec4 project_pos = project_position(vec4(a_Position, 1.0)); - gl_Position = project_common_position_to_clipspace_v2(vec4(project_pos.xyz, 1.0)); + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0)); } diff --git a/packages/layers/src/raster/index.ts b/packages/layers/src/raster/index.ts index 3025f494aa6..d4b143edfc5 100644 --- a/packages/layers/src/raster/index.ts +++ b/packages/layers/src/raster/index.ts @@ -4,7 +4,8 @@ import type { IRasterLayerStyleOptions } from '../core/interface'; import { rampColor2legend } from '../utils/rampcolor_legend'; import type { RasterModelType } from './models/index'; import RasterModels from './models/index'; -export default class RaterLayer extends BaseLayer { + +export default class RasterLayer extends BaseLayer { public type: string = 'RasterLayer'; public async buildModels() { const modelType = this.getModelType(); diff --git a/packages/layers/src/raster/models/raster.ts b/packages/layers/src/raster/models/raster.ts index 5526a249a51..1ce9338256e 100644 --- a/packages/layers/src/raster/models/raster.ts +++ b/packages/layers/src/raster/models/raster.ts @@ -2,12 +2,18 @@ import type { IEncodeFeature, IModel, ITexture2D } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; import { getDefaultDomain } from '@antv/l7-utils'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import type { IRasterLayerStyleOptions } from '../../core/interface'; import { RasterImageTriangulation } from '../../core/triangulation'; import rasterFrag from '../shaders/raster/raster_2d_frag.glsl'; import rasterVert from '../shaders/raster/raster_2d_vert.glsl'; export default class RasterModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + UV: 9, + }); + } + protected texture: ITexture2D; protected colorTexture: ITexture2D; public getUninforms() { @@ -87,6 +93,7 @@ export default class RasterModel extends BaseModel { height, /** * WebGL1 allow the combination of gl.LUMINANCE & gl.FLOAT with OES_texture_float + * TODO: https://github.com/antvis/g-device-api/issues/188 */ format: queryVerdorInfo() === 'WebGL1' ? gl.LUMINANCE : gl.RED, type: gl.FLOAT, @@ -97,6 +104,7 @@ export default class RasterModel extends BaseModel { moduleName: 'rasterImageData', vertexShader: rasterVert, fragmentShader: rasterFrag, + defines: this.getDefines(), triangulation: RasterImageTriangulation, primitive: gl.TRIANGLES, depth: { enable: false }, @@ -111,12 +119,15 @@ export default class RasterModel extends BaseModel { } protected registerBuiltinAttributes() { + // 注册 Position 属性 64 位地位部分,经纬度数据开启双精度,避免大于 22 层级以上出现数据偏移 + this.registerPosition64LowAttribute(); + // point layer size; this.styleAttributeService.registerStyleAttribute({ name: 'uv', type: AttributeType.Attribute, descriptor: { - shaderLocation: ShaderLocation.UV, + shaderLocation: this.attributeLocation.UV, name: 'a_Uv', buffer: { // give the WebGL driver a hint that this buffer may change diff --git a/packages/layers/src/raster/models/rasterRgb.ts b/packages/layers/src/raster/models/rasterRgb.ts index e75512d7b76..dc756b9366c 100644 --- a/packages/layers/src/raster/models/rasterRgb.ts +++ b/packages/layers/src/raster/models/rasterRgb.ts @@ -1,12 +1,18 @@ import type { IEncodeFeature, IModel, ITexture2D } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import type { IRasterLayerStyleOptions } from '../../core/interface'; import { RasterImageTriangulation } from '../../core/triangulation'; import rasterFrag from '../shaders/rgb/raster_rgb_frag.glsl'; import rasterVert from '../shaders/rgb/raster_rgb_vert.glsl'; export default class RasterModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + UV: 9, + }); + } + protected texture: ITexture2D; protected dataOption: any = {}; @@ -89,6 +95,7 @@ export default class RasterModel extends BaseModel { moduleName: 'rasterImageDataRGBA', vertexShader: rasterVert, fragmentShader: rasterFrag, + defines: this.getDefines(), triangulation: RasterImageTriangulation, primitive: gl.TRIANGLES, depth: { enable: false }, @@ -106,13 +113,16 @@ export default class RasterModel extends BaseModel { } protected registerBuiltinAttributes() { + // 注册 Position 属性 64 位地位部分,经纬度数据开启双精度,避免大于 22 层级以上出现数据偏移 + this.registerPosition64LowAttribute(); + // point layer size; this.styleAttributeService.registerStyleAttribute({ name: 'uv', type: AttributeType.Attribute, descriptor: { name: 'a_Uv', - shaderLocation: ShaderLocation.UV, + shaderLocation: this.attributeLocation.UV, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, diff --git a/packages/layers/src/raster/models/rasterTerrainRgb.ts b/packages/layers/src/raster/models/rasterTerrainRgb.ts index b741995f717..f77ff23550f 100644 --- a/packages/layers/src/raster/models/rasterTerrainRgb.ts +++ b/packages/layers/src/raster/models/rasterTerrainRgb.ts @@ -2,13 +2,19 @@ import type { IEncodeFeature, IModel, ITexture2D } from '@antv/l7-core'; import { AttributeType, gl } from '@antv/l7-core'; import { getDefaultDomain } from '@antv/l7-utils'; import BaseModel from '../../core/BaseModel'; -import { ShaderLocation } from '../../core/CommonStyleAttribute'; import type { IRasterTerrainLayerStyleOptions } from '../../core/interface'; import { RasterImageTriangulation } from '../../core/triangulation'; import Raster_terrainFrag from '../shaders/terrain/terrain_rgb_frag.glsl'; import Raster_terrainVert from '../shaders/terrain/terrain_rgb_vert.glsl'; export default class RasterTerrainRGB extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + UV: 9, + }); + } + protected texture: ITexture2D; protected getCommonUniformsInfo(): { uniformsArray: number[]; @@ -66,6 +72,7 @@ export default class RasterTerrainRGB extends BaseModel { moduleName: 'RasterTileDataImage', vertexShader: Raster_terrainVert, fragmentShader: Raster_terrainFrag, + defines: this.getDefines(), triangulation: RasterImageTriangulation, primitive: gl.TRIANGLES, depth: { enable: false }, @@ -82,12 +89,15 @@ export default class RasterTerrainRGB extends BaseModel { } protected registerBuiltinAttributes() { + // 注册 Position 属性 64 位地位部分,经纬度数据开启双精度,避免大于 22 层级以上出现数据偏移 + this.registerPosition64LowAttribute(); + this.styleAttributeService.registerStyleAttribute({ name: 'uv', type: AttributeType.Attribute, descriptor: { name: 'a_Uv', - shaderLocation: ShaderLocation.UV, + shaderLocation: this.attributeLocation.UV, buffer: { usage: gl.DYNAMIC_DRAW, data: [], diff --git a/packages/layers/src/raster/shaders/raster/raster_2d_vert.glsl b/packages/layers/src/raster/shaders/raster/raster_2d_vert.glsl index 78dcd0b7ee4..1a534f443c9 100644 --- a/packages/layers/src/raster/shaders/raster/raster_2d_vert.glsl +++ b/packages/layers/src/raster/shaders/raster/raster_2d_vert.glsl @@ -1,6 +1,6 @@ - -layout(location = 0) in vec3 a_Position; -layout(location = 14) in vec2 a_Uv; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_POSITION_64LOW) in vec2 a_Position64Low; +layout(location = ATTRIBUTE_LOCATION_UV) in vec2 a_Uv; layout(std140) uniform commonUniforms { vec2 u_domain; @@ -15,7 +15,7 @@ out vec2 v_texCoord; #pragma include "projection" void main() { - v_texCoord = a_Uv; - vec4 project_pos = project_position(vec4(a_Position, 1.0)); - gl_Position = project_common_position_to_clipspace_v2(vec4(project_pos.xy,0., 1.0)); + v_texCoord = a_Uv; + vec4 project_pos = project_position(vec4(a_Position, 1.0), a_Position64Low); + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy, 0.0, 1.0)); } diff --git a/packages/layers/src/raster/shaders/rgb/raster_rgb_vert.glsl b/packages/layers/src/raster/shaders/rgb/raster_rgb_vert.glsl index a57fa642ed0..94b8c9acee2 100644 --- a/packages/layers/src/raster/shaders/rgb/raster_rgb_vert.glsl +++ b/packages/layers/src/raster/shaders/rgb/raster_rgb_vert.glsl @@ -1,13 +1,13 @@ - -layout(location = 0) in vec3 a_Position; -layout(location = 14) in vec2 a_Uv; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_POSITION_64LOW) in vec2 a_Position64Low; +layout(location = ATTRIBUTE_LOCATION_UV) in vec2 a_Uv; layout(std140) uniform commonUniforms { - vec2 u_rminmax; - vec2 u_gminmax; - vec2 u_bminmax; - float u_opacity; - float u_noDataValue; + vec2 u_rminmax; + vec2 u_gminmax; + vec2 u_bminmax; + float u_opacity; + float u_noDataValue; }; out vec2 v_texCoord; @@ -15,7 +15,7 @@ out vec2 v_texCoord; #pragma include "projection" void main() { - v_texCoord = a_Uv; - vec4 project_pos = project_position(vec4(a_Position, 1.0)); - gl_Position = project_common_position_to_clipspace_v2(vec4(project_pos.xy,0., 1.0)); + v_texCoord = a_Uv; + vec4 project_pos = project_position(vec4(a_Position, 1.0), a_Position64Low); + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy, 0.0, 1.0)); } diff --git a/packages/layers/src/raster/shaders/terrain/terrain_rgb_vert.glsl b/packages/layers/src/raster/shaders/terrain/terrain_rgb_vert.glsl index 11ffd4662b8..4a19fd3afcf 100644 --- a/packages/layers/src/raster/shaders/terrain/terrain_rgb_vert.glsl +++ b/packages/layers/src/raster/shaders/terrain/terrain_rgb_vert.glsl @@ -1,19 +1,19 @@ -layout(location = 0) in vec3 a_Position; -layout(location = 14) in vec2 a_Uv; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_UV) in vec2 a_Uv; layout(std140) uniform commonUniforms { - vec4 u_unpack; - vec2 u_domain; - float u_opacity; - float u_noDataValue; - float u_clampLow; - float u_clampHigh; + vec4 u_unpack; + vec2 u_domain; + float u_opacity; + float u_noDataValue; + float u_clampLow; + float u_clampHigh; }; out vec2 v_texCoord; #pragma include "projection" void main() { - v_texCoord = a_Uv; - vec4 project_pos = project_position(vec4(a_Position, 1.0)); - gl_Position = project_common_position_to_clipspace_v2(vec4(project_pos.xy,0., 1.0)); + v_texCoord = a_Uv; + vec4 project_pos = project_position(vec4(a_Position, 1.0)); + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy, 0.0, 1.0)); } diff --git a/packages/layers/src/tile/core/BaseLayer.ts b/packages/layers/src/tile/core/BaseLayer.ts index edb728bcdb5..71a9bd5f92f 100644 --- a/packages/layers/src/tile/core/BaseLayer.ts +++ b/packages/layers/src/tile/core/BaseLayer.ts @@ -86,17 +86,6 @@ export default class BaseTileLayer { const { latLonBounds, zoom } = this.getCurrentView(); - if (this.mapService.version === 'GAODE1.x') { - const { visible } = this.parent.getLayerConfig(); - if (zoom < 2 && visible) { - this.parent.updateLayerConfig({ visible: false }); - this.layerService.reRender(); - } else if (zoom >= 2 && !visible) { - this.parent.updateLayerConfig({ visible: true }); - this.layerService.reRender(); - } - } - if ( this.lastViewStates && this.lastViewStates.zoom === zoom && diff --git a/packages/layers/src/utils/extrude_polyline.ts b/packages/layers/src/utils/extrude_polyline.ts index 4b650038bc3..c4213155073 100644 --- a/packages/layers/src/utils/extrude_polyline.ts +++ b/packages/layers/src/utils/extrude_polyline.ts @@ -21,6 +21,7 @@ export function computeMiter( const tmpvec = vec2.fromValues(-start[1], start[0]); return [halfThick / vec2.dot(miter, tmpvec), miter]; } + export function computeNormal(out: vec2, dir: vec2) { return vec2.set(out, -dir[1], dir[0]); } @@ -122,111 +123,6 @@ export default class ExtrudePolyline { return complex; } - public simpleExtrude_gaode2(points: number[][], originPoints: number[][]) { - const complex = this.complex; - if (points.length <= 1) { - return complex; - } - this.lastFlip = -1; - this.started = false; - this.normal = null; - this.totalDistance = 0; - // 去除数组里重复的点 - // points = getArrayUnique(points); - const total = points.length; - let count = complex.startIndex; - for (let i = 1; i < total; i++) { - const last = points[i - 1]; - last.push(originPoints[i - 1][2] ?? 0); - // @ts-ignore - const originLast = originPoints[i - 1] as vec3; - - const cur = points[i]; - cur.push(originPoints[i][2] ?? 0); - // @ts-ignore - const originCur = originPoints[i] as vec3; - - const next = i < points.length - 1 ? [...points[i + 1], originPoints[i + 1][2] ?? 0] : null; - const originNext = i < originPoints.length - 1 ? originPoints[i + 1] : null; - - const amt = this.simpleSegment( - complex, - count, - // @ts-ignore - last as vec3, - // @ts-ignore - cur as vec3, - // @ts-ignore - next as vec3, - // @ts-ignore - originLast, - originCur, - // @ts-ignore - originNext as vec3, - ); - count += amt; - } - if (this.dash) { - for (let i = 0; i < complex.positions.length / 6; i++) { - complex.positions[i * 6 + 5] = this.totalDistance; - } - } - complex.startIndex = complex.positions.length / 6; - return complex; - } - - public extrude_gaode2(points: number[][], originPoints: number[][]) { - const complex = this.complex; - if (points.length <= 1) { - return complex; - } - this.lastFlip = -1; - this.started = false; - this.normal = null; - this.totalDistance = 0; - // 去除数组里重复的点 - // points = getArrayUnique(points); - const total = points.length; - let count = complex.startIndex; - for (let i = 1; i < total; i++) { - const last = points[i - 1]; - last.push(originPoints[i - 1][2] ?? 0); - // @ts-ignore - const originLast = originPoints[i - 1] as vec3; - - const cur = points[i]; - cur.push(originPoints[i][2] ?? 0); - // @ts-ignore - const originCur = originPoints[i] as vec3; - - const next = i < points.length - 1 ? [...points[i + 1], originPoints[i + 1][2] ?? 0] : null; - const originNext = i < originPoints.length - 1 ? originPoints[i + 1] : null; - - const amt = this.segment_gaode2( - complex, - count, - // @ts-ignore - last as vec3, - // @ts-ignore - cur as vec3, - // @ts-ignore - next as vec3, - // @ts-ignore - originLast, - originCur, - // @ts-ignore - originNext as vec3, - ); - count += amt; - } - if (this.dash) { - for (let i = 0; i < complex.positions.length / 6; i++) { - complex.positions[i * 6 + 5] = this.totalDistance; - } - } - complex.startIndex = complex.positions.length / 6; - return complex; - } public extrude(points: number[][]) { const complex = this.complex; if (points.length <= 1) { @@ -335,205 +231,7 @@ export default class ExtrudePolyline { } return count; } - private segment_gaode2( - complex: any, - index: number, - last: vec3, - cur: vec3, - next: vec3, - originLast: vec3, - originCur: vec3, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - originNext: vec3, - ) { - let count = 0; - const indices = complex.indices; - const positions = complex.positions; - const normals = complex.normals; - const capSquare = this.cap === 'square'; - const joinBevel = this.join === 'bevel'; - const flatCur = aProjectFlat([originCur[0], originCur[1]]) as [number, number]; - const flatLast = aProjectFlat([originLast[0], originLast[1]]) as [number, number]; - // @ts-ignore - direction(lineA, cur as vec3, last as vec3); - let segmentDistance = 0; - if (this.dash) { - // @ts-ignore - segmentDistance = this.lineSegmentDistance(flatCur, flatLast); - this.totalDistance += segmentDistance; - } - if (!this.normal) { - this.normal = vec2.create(); - computeNormal(this.normal, lineA); - } - if (!this.started) { - this.started = true; - - // if the end cap is type square, we can just push the verts out a bit - if (capSquare) { - // vec2.scaleAndAdd(capEnd, last, lineA, -this.thickness); - const out1 = vec2.create(); - const out2 = vec2.create(); - vec2.add(out1, this.normal, lineA); - vec2.add(out2, this.normal, lineA); - normals.push(out2[0], out2[1], 0); - normals.push(out1[0], out1[1], 0); - positions.push( - last[0], - last[1], - last[2] | 0, - this.totalDistance - segmentDistance, - -this.thickness, - last[2] | 0, - ); - this.complex.indexes.push(this.currentIndex); - positions.push( - last[0], - last[1], - last[2] | 0, - this.totalDistance - segmentDistance, - this.thickness, - last[2] | 0, - ); - this.complex.indexes.push(this.currentIndex); - this.currentIndex++; - } else { - this.extrusions( - positions, - normals, - last, - this.normal, - this.thickness, - this.totalDistance - segmentDistance, - ); - } - } - - indices.push(index + 0, index + 1, index + 2); - - if (!next) { - computeNormal(this.normal, lineA); - if (capSquare) { - const out1 = vec2.create(); - const out2 = vec2.create(); - vec2.sub(out2, lineA, this.normal); - vec2.add(out1, lineA, this.normal); - - normals.push(out2[0], out2[1], 0); - normals.push(out1[0], out1[1], 0); - - positions.push(cur[0], cur[1], cur[2] | 0, this.totalDistance, this.thickness, cur[2] | 0); - this.complex.indexes.push(this.currentIndex); - positions.push(cur[0], cur[1], cur[2] | 0, this.totalDistance, this.thickness, cur[2] | 0); - this.complex.indexes.push(this.currentIndex); - this.currentIndex++; - } else { - this.extrusions(positions, normals, cur, this.normal, this.thickness, this.totalDistance); - } - indices.push( - ...(this.lastFlip === 1 - ? [index, index + 2, index + 3] - : [index + 2, index + 1, index + 3]), - ); - count += 2; - } else { - // @ts-ignore - if (isPointEqual(cur as vec2, next as vec2)) { - vec2.add( - // @ts-ignore - next as vec2, - // @ts-ignore - cur as vec2, - vec2.normalize( - // @ts-ignore - next as vec2, - // @ts-ignore - vec2.subtract(next as vec2, cur as vec2, last as vec2), - ), - ); - } - // @ts-ignore - direction(lineB, next as vec2, cur as vec2); - // stores tangent & miter - - const [miterLen, miter] = computeMiter(tangent, vec2.create(), lineA, lineB, this.thickness); - // normal(tmp, lineA) - - // get orientation - let flip = vec2.dot(tangent, this.normal) < 0 ? -1 : 1; - let bevel = joinBevel; - if (!bevel && this.join === 'miter') { - const limit = miterLen; - if (limit > this.miterLimit) { - bevel = true; - } - } - - if (bevel) { - normals.push(this.normal[0], this.normal[1], 0); - normals.push(miter[0], miter[1], 0); - - positions.push( - cur[0], - cur[1], - cur[2] | 0, - this.totalDistance, - -this.thickness * flip, - cur[2] | 0, - ); - this.complex.indexes.push(this.currentIndex); - positions.push( - cur[0], - cur[1], - cur[2] | 0, - this.totalDistance, - this.thickness * flip, - cur[2] | 0, - ); - this.complex.indexes.push(this.currentIndex); - this.currentIndex++; - indices.push( - ...(this.lastFlip !== -flip - ? [index, index + 2, index + 3] - : [index + 2, index + 1, index + 3]), - ); - - // now add the bevel triangle - indices.push(index + 2, index + 3, index + 4); - - computeNormal(tmp, lineB); - vec2.copy(this.normal, tmp); // store normal for next round - normals.push(this.normal[0], this.normal[1], 0); - positions.push( - cur[0], - cur[1], - cur[2] | 0, - this.totalDistance, - -this.thickness * flip, - cur[2] | 0, - ); - this.complex.indexes.push(this.currentIndex); - this.currentIndex++; - count += 3; - } else { - this.extrusions(positions, normals, cur, miter, miterLen, this.totalDistance); - indices.push( - ...(this.lastFlip === 1 - ? [index, index + 2, index + 3] - : [index + 2, index + 1, index + 3]), - ); - - flip = -1; - - // the miter is now the normal for our next join - vec2.copy(this.normal, miter); - count += 2; - } - this.lastFlip = flip; - } - return count; - } private segment(complex: any, index: number, last: vec3, cur: vec3, next: vec3) { let count = 0; const indices = complex.indices; @@ -720,6 +418,7 @@ export default class ExtrudePolyline { } return count; } + private extrusions( positions: number[], normals: number[], @@ -736,6 +435,7 @@ export default class ExtrudePolyline { this.complex.indexes.push(this.currentIndex); this.currentIndex++; } + private lineSegmentDistance(b1: vec3, a1: vec3) { const dx = a1[0] - b1[0]; const dy = a1[1] - b1[1]; diff --git a/packages/layers/src/wind/models/wind.ts b/packages/layers/src/wind/models/wind.ts index 175ad10ea7f..53382793dce 100644 --- a/packages/layers/src/wind/models/wind.ts +++ b/packages/layers/src/wind/models/wind.ts @@ -28,6 +28,13 @@ const defaultRampColors = { }; export default class WindModel extends BaseModel { + protected get attributeLocation() { + return Object.assign(super.attributeLocation, { + MAX: super.attributeLocation.MAX, + UV: 9, + }); + } + protected texture: ITexture2D; private colorModel: IModel; private wind: IWind; @@ -116,6 +123,7 @@ export default class WindModel extends BaseModel { moduleName: 'wind', vertexShader: WindVert, fragmentShader: WindFrag, + defines: this.getDefines(), triangulation: RasterImageTriangulation, primitive: gl.TRIANGLES, depth: { enable: false }, @@ -149,6 +157,7 @@ export default class WindModel extends BaseModel { type: AttributeType.Attribute, descriptor: { name: 'a_Uv', + shaderLocation: this.attributeLocation.UV, buffer: { // give the WebGL driver a hint that this buffer may change usage: gl.DYNAMIC_DRAW, diff --git a/packages/layers/src/wind/shaders/wind_vert.glsl b/packages/layers/src/wind/shaders/wind_vert.glsl index 022b2cb46eb..66c06235c2e 100644 --- a/packages/layers/src/wind/shaders/wind_vert.glsl +++ b/packages/layers/src/wind/shaders/wind_vert.glsl @@ -1,13 +1,14 @@ precision highp float; uniform mat4 u_ModelMatrix; -attribute vec3 a_Position; -attribute vec2 a_Uv; +layout(location = ATTRIBUTE_LOCATION_POSITION) in vec3 a_Position; +layout(location = ATTRIBUTE_LOCATION_UV) in vec2 a_Uv; + varying vec2 v_texCoord; #pragma include "projection" void main() { - v_texCoord = a_Uv; - vec4 project_pos = project_position(vec4(a_Position, 1.0)); + v_texCoord = a_Uv; + vec4 project_pos = project_position(vec4(a_Position, 1.0)); - gl_Position = project_common_position_to_clipspace_v2(vec4(project_pos.xy,0., 1.0)); + gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy, 0.0, 1.0)); } diff --git a/packages/map/CHANGELOG.md b/packages/map/CHANGELOG.md index 97a0f29a001..e6f9adf254c 100644 --- a/packages/map/CHANGELOG.md +++ b/packages/map/CHANGELOG.md @@ -1,5 +1,63 @@ # @antv/l7-map +## 2.21.11-beta.7 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-utils@2.21.11-beta.7 + +## 2.21.11-beta.6 + +### Patch Changes + +- [#2521](https://github.com/antvis/L7/pull/2521) [`7e38a83`](https://github.com/antvis/L7/commit/7e38a83d9324fb9443f5a04e6d2fc9a1fef9c17c) Thanks [@lvisei](https://github.com/lvisei)! - refactor: 升级新版一方地图交互事件机制,解决抖动问题 + +- Updated dependencies []: + - @antv/l7-utils@2.21.11-beta.6 + +## 2.21.11-beta.5 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-utils@2.21.11-beta.5 + +## 2.21.11-beta.4 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-utils@2.21.11-beta.4 + +## 2.21.11-beta.3 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-utils@2.21.11-beta.3 + +## 2.21.11-beta.2 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-utils@2.21.11-beta.2 + +## 2.21.11-beta.1 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-utils@2.21.11-beta.1 + +## 2.21.11-beta.0 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-utils@2.21.11-beta.0 + ## 2.21.10 ### Patch Changes diff --git a/packages/map/README.md b/packages/map/README.md index 74ed6847c3d..d10e2d1591d 100644 --- a/packages/map/README.md +++ b/packages/map/README.md @@ -1,11 +1,32 @@ -# `map` +## Map -> TODO: description +Map fork from [maplibre-gl-js@4.3.2](https://github.com/maplibre/maplibre-gl-js), keep event loop, responds user interaction and updates the internal state of the map (current viewport, camera angle, etc.) -## Usage +```mermaid +sequenceDiagram + actor user + participant DOM + participant handler_manager + participant handler + participant camera + participant transform + participant map -``` -const map = require('map'); + user->>camera: map#setCenter, map#panTo + camera->>transform: update + camera->>map: fire move event + map->>map: _render() -// TODO: DEMONSTRATE API + user->>DOM: resize, pan,
click, scroll,
... + DOM->>handler_manager: DOM events + handler_manager->>handler: forward event + handler-->>handler_manager: HandlerResult + handler_manager->>transform: update + handler_manager->>map: fire move event + map->>map: _render() ``` + +- [Transform](./src/geo/transform.ts) holds the current viewport details (pitch, zoom, bearing, bounds, etc.). Two places in the code update transform directly: + - [Camera](./src/camera.ts) (parent class of [Map](./src/map)) in response to explicit calls to [Camera#panTo](./src/camera.ts#L207), [Camera#setCenter](./src/camera.ts#L169) + - [HandlerManager](./src/handler_manager.ts) in response to DOM events. It forwards those events to interaction processors that live in [src/ui/handler](./src/handler), which accumulate a merged [HandlerResult](./src/handler_manager.ts#L64) that kick off a render frame loop, decreasing the inertia and nudging map.transform by that amount on each frame from [HandlerManager#\_updateMapTransform()](./src/handler_manager.ts#L413). That loop continues in the inertia decreases to 0. +- Both camera and handler_manager are responsible for firing `move`, `zoom`, `movestart`, `moveend`, ... events on the map after they update transform. Each of these events (along with style changes and data load events) triggers a call to [Map#\_render()](./src/map.ts#L2480) which renders a single frame of the map. diff --git a/packages/map/__tests__/camera.spec.ts b/packages/map/__tests__/camera.spec.ts new file mode 100644 index 00000000000..6167baf1100 --- /dev/null +++ b/packages/map/__tests__/camera.spec.ts @@ -0,0 +1,2460 @@ +import type { CameraOptions } from '../src/map/camera'; +import { Camera } from '../src/map/camera'; +import { Transform } from '../src/map/geo/transform'; +import { browser } from '../src/map/util/browser'; +import type { TaskID } from '../src/map/util/task_queue'; +import { TaskQueue } from '../src/map/util/task_queue'; + +import { LngLat } from '../src/map/geo/lng_lat'; +import { LngLatBounds } from '../src/map/geo/lng_lat_bounds'; +import { mercatorZfromAltitude } from '../src/map/geo/mercator_coordinate'; +import type { Event } from '../src/map/util/evented'; +import { fixedLngLat, fixedNum } from './libs/fixed'; +import { setMatchMedia } from './libs/util'; + +beforeEach(() => { + setMatchMedia(); + Object.defineProperty(browser, 'prefersReducedMotion', { value: false }); +}); + +class CameraMock extends Camera { + // eslint-disable-next-line + _requestRenderFrame(a: () => void): TaskID { + return undefined; + } + + _cancelRenderFrame(): void { + return undefined; + } +} + +function attachSimulateFrame(camera) { + const queue = new TaskQueue(); + camera._requestRenderFrame = (cb) => queue.add(cb); + camera._cancelRenderFrame = (id) => queue.remove(id); + camera.simulateFrame = () => queue.run(); + return camera; +} + +function createCamera(options?) { + options = options || {}; + + const transform = new Transform(0, 20, 0, 60, options.renderWorldCopies); + transform.resize(512, 512); + + const camera = attachSimulateFrame(new CameraMock(transform, {} as any)).jumpTo(options); + + camera._update = () => {}; + + return camera; +} + +function assertTransitionTime(done, camera, min, max) { + let startTime; + camera + .on('movestart', () => { + startTime = new Date(); + }) + .on('moveend', () => { + const endTime = new Date(); + const timeDiff = endTime.getTime() - startTime.getTime(); + expect(timeDiff >= min && timeDiff < max).toBeTruthy(); + done(); + }); +} + +describe('#calculateCameraOptionsFromTo', () => { + // Choose initial zoom to avoid center being constrained by mercator latitude limits. + const camera = createCamera({ zoom: 1 }); + + test('look at north', () => { + const cameraOptions: CameraOptions = camera.calculateCameraOptionsFromTo( + { lng: 1, lat: 0 }, + 0, + { lng: 1, lat: 1 }, + ); + expect(cameraOptions).toBeDefined(); + expect(cameraOptions.center).toBeDefined(); + expect(cameraOptions.bearing).toBeCloseTo(0); + }); + + test('look at west', () => { + const cameraOptions = camera.calculateCameraOptionsFromTo({ lng: 1, lat: 0 }, 0, { + lng: 0, + lat: 0, + }); + expect(cameraOptions).toBeDefined(); + expect(cameraOptions.bearing).toBeCloseTo(-90); + }); + + test('pitch 45', () => { + // altitude same as grounddistance => 45° + // distance between lng x and lng x+1 is 111.2km at same lat + const cameraOptions: CameraOptions = camera.calculateCameraOptionsFromTo( + { lng: 1, lat: 0 }, + 111200, + { lng: 0, lat: 0 }, + ); + expect(cameraOptions).toBeDefined(); + expect(cameraOptions.pitch).toBeCloseTo(45); + }); + + test('pitch 90', () => { + const cameraOptions = camera.calculateCameraOptionsFromTo({ lng: 1, lat: 0 }, 0, { + lng: 0, + lat: 0, + }); + expect(cameraOptions).toBeDefined(); + expect(cameraOptions.pitch).toBeCloseTo(90); + }); + + test('pitch 153.435', () => { + // distance between lng x and lng x+1 is 111.2km at same lat + // (elevation difference of cam and center) / 2 = grounddistance => + // acos(111.2 / sqrt(111.2² + (111.2 * 2)²)) = acos(1/sqrt(5)) => 63.435 + 90 (looking up) = 153.435 + const cameraOptions: CameraOptions = camera.calculateCameraOptionsFromTo( + { lng: 1, lat: 0 }, + 111200, + { lng: 0, lat: 0 }, + 111200 * 3, + ); + expect(cameraOptions).toBeDefined(); + expect(cameraOptions.pitch).toBeCloseTo(153.435); + }); + + test('zoom distance 1000', () => { + const expectedZoom = Math.log2( + camera.transform.cameraToCenterDistance / + mercatorZfromAltitude(1000, 0) / + camera.transform.tileSize, + ); + const cameraOptions = camera.calculateCameraOptionsFromTo( + { lng: 0, lat: 0 }, + 0, + { lng: 0, lat: 0 }, + 1000, + ); + + expect(cameraOptions).toBeDefined(); + expect(cameraOptions.zoom).toBeCloseTo(expectedZoom); + }); + + test('zoom distance 1 lng (111.2km), 111.2km altitude away', () => { + const expectedZoom = Math.log2( + camera.transform.cameraToCenterDistance / + mercatorZfromAltitude(Math.hypot(111200, 111200), 0) / + camera.transform.tileSize, + ); + const cameraOptions = camera.calculateCameraOptionsFromTo( + { lng: 0, lat: 0 }, + 0, + { lng: 1, lat: 0 }, + 111200, + ); + + expect(cameraOptions).toBeDefined(); + expect(cameraOptions.zoom).toBeCloseTo(expectedZoom); + }); + + test('same To as From error', () => { + expect(() => { + camera.calculateCameraOptionsFromTo({ lng: 0, lat: 0 }, 0, { lng: 0, lat: 0 }, 0); + }).toThrow(); + }); +}); + +describe('#jumpTo', () => { + // Choose initial zoom to avoid center being constrained by mercator latitude limits. + const camera = createCamera({ zoom: 1 }); + + test('sets center', () => { + camera.jumpTo({ center: [1, 2] }); + expect(camera.getCenter()).toEqual({ lng: 1, lat: 2 }); + }); + + test('throws on invalid center argument', () => { + expect(() => { + camera.jumpTo({ center: 1 }); + }).toThrow(Error); + }); + + test('keeps current center if not specified', () => { + camera.jumpTo({}); + expect(camera.getCenter()).toEqual({ lng: 1, lat: 2 }); + }); + + test('sets zoom', () => { + camera.jumpTo({ zoom: 3 }); + expect(camera.getZoom()).toBe(3); + }); + + test('keeps current zoom if not specified', () => { + camera.jumpTo({}); + expect(camera.getZoom()).toBe(3); + }); + + test('sets bearing', () => { + camera.jumpTo({ bearing: 4 }); + expect(camera.getBearing()).toBe(4); + }); + + test('keeps current bearing if not specified', () => { + camera.jumpTo({}); + expect(camera.getBearing()).toBe(4); + }); + + test('sets pitch', () => { + camera.jumpTo({ pitch: 45 }); + expect(camera.getPitch()).toBe(45); + }); + + test('keeps current pitch if not specified', () => { + camera.jumpTo({}); + expect(camera.getPitch()).toBe(45); + }); + + test('sets multiple properties', () => { + camera.jumpTo({ + center: [10, 20], + zoom: 10, + bearing: 180, + pitch: 60, + }); + expect(camera.getCenter()).toEqual({ lng: 10, lat: 20 }); + expect(camera.getZoom()).toBe(10); + expect(camera.getBearing()).toBe(180); + expect(camera.getPitch()).toBe(60); + }); + + test('emits move events, preserving eventData', (done) => { + let started, moved, ended; + const eventData = { data: 'ok' }; + + camera + .on('movestart', (d) => { + started = d.data; + }) + .on('move', (d) => { + moved = d.data; + }) + .on('moveend', (d) => { + ended = d.data; + }); + + camera.jumpTo({ center: [1, 2] }, eventData); + expect(started).toBe('ok'); + expect(moved).toBe('ok'); + expect(ended).toBe('ok'); + done(); + }); + + test('emits zoom events, preserving eventData', (done) => { + let started, zoomed, ended; + const eventData = { data: 'ok' }; + + camera + .on('zoomstart', (d) => { + started = d.data; + }) + .on('zoom', (d) => { + zoomed = d.data; + }) + .on('zoomend', (d) => { + ended = d.data; + }); + + camera.jumpTo({ zoom: 3 }, eventData); + expect(started).toBe('ok'); + expect(zoomed).toBe('ok'); + expect(ended).toBe('ok'); + done(); + }); + + test('emits rotate events, preserving eventData', (done) => { + let started, rotated, ended; + const eventData = { data: 'ok' }; + + camera + .on('rotatestart', (d) => { + started = d.data; + }) + .on('rotate', (d) => { + rotated = d.data; + }) + .on('rotateend', (d) => { + ended = d.data; + }); + + camera.jumpTo({ bearing: 90 }, eventData); + expect(started).toBe('ok'); + expect(rotated).toBe('ok'); + expect(ended).toBe('ok'); + done(); + }); + + test('emits pitch events, preserving eventData', (done) => { + let started, pitched, ended; + const eventData = { data: 'ok' }; + + camera + .on('pitchstart', (d) => { + started = d.data; + }) + .on('pitch', (d) => { + pitched = d.data; + }) + .on('pitchend', (d) => { + ended = d.data; + }); + + camera.jumpTo({ pitch: 10 }, eventData); + expect(started).toBe('ok'); + expect(pitched).toBe('ok'); + expect(ended).toBe('ok'); + done(); + }); + + test('cancels in-progress easing', () => { + camera.panTo([3, 4]); + expect(camera.isEasing()).toBeTruthy(); + camera.jumpTo({ center: [1, 2] }); + expect(!camera.isEasing()).toBeTruthy(); + }); +}); + +describe('#setCenter', () => { + // Choose initial zoom to avoid center being constrained by mercator latitude limits. + const camera = createCamera({ zoom: 1 }); + + test('sets center', () => { + camera.setCenter([1, 2]); + expect(camera.getCenter()).toEqual({ lng: 1, lat: 2 }); + }); + + test('throws on invalid center argument', () => { + expect(() => { + camera.jumpTo({ center: 1 }); + }).toThrow(Error); + }); + + test('emits move events, preserving eventData', (done) => { + let started, moved, ended; + const eventData = { data: 'ok' }; + + camera + .on('movestart', (d) => { + started = d.data; + }) + .on('move', (d) => { + moved = d.data; + }) + .on('moveend', (d) => { + ended = d.data; + }); + + camera.setCenter([10, 20], eventData); + expect(started).toBe('ok'); + expect(moved).toBe('ok'); + expect(ended).toBe('ok'); + done(); + }); + + test('cancels in-progress easing', () => { + camera.panTo([3, 4]); + expect(camera.isEasing()).toBeTruthy(); + camera.setCenter([1, 2]); + expect(!camera.isEasing()).toBeTruthy(); + }); +}); + +describe('#setZoom', () => { + const camera = createCamera(); + + test('sets zoom', () => { + camera.setZoom(3); + expect(camera.getZoom()).toBe(3); + }); + + test('emits move and zoom events, preserving eventData', (done) => { + let movestarted, moved, moveended, zoomstarted, zoomed, zoomended; + const eventData = { data: 'ok' }; + + camera + .on('movestart', (d) => { + movestarted = d.data; + }) + .on('move', (d) => { + moved = d.data; + }) + .on('moveend', (d) => { + moveended = d.data; + }) + .on('zoomstart', (d) => { + zoomstarted = d.data; + }) + .on('zoom', (d) => { + zoomed = d.data; + }) + .on('zoomend', (d) => { + zoomended = d.data; + }); + + camera.setZoom(4, eventData); + expect(movestarted).toBe('ok'); + expect(moved).toBe('ok'); + expect(moveended).toBe('ok'); + expect(zoomstarted).toBe('ok'); + expect(zoomed).toBe('ok'); + expect(zoomended).toBe('ok'); + done(); + }); + + test('cancels in-progress easing', () => { + camera.panTo([3, 4]); + expect(camera.isEasing()).toBeTruthy(); + camera.setZoom(5); + expect(!camera.isEasing()).toBeTruthy(); + }); +}); + +describe('#setBearing', () => { + const camera = createCamera(); + + test('sets bearing', () => { + camera.setBearing(4); + expect(camera.getBearing()).toBe(4); + }); + + test('emits move and rotate events, preserving eventData', (done) => { + let movestarted, moved, moveended, rotatestarted, rotated, rotateended; + const eventData = { data: 'ok' }; + + camera + .on('movestart', (d) => { + movestarted = d.data; + }) + .on('move', (d) => { + moved = d.data; + }) + .on('moveend', (d) => { + moveended = d.data; + }) + .on('rotatestart', (d) => { + rotatestarted = d.data; + }) + .on('rotate', (d) => { + rotated = d.data; + }) + .on('rotateend', (d) => { + rotateended = d.data; + }); + + camera.setBearing(5, eventData); + expect(movestarted).toBe('ok'); + expect(moved).toBe('ok'); + expect(moveended).toBe('ok'); + expect(rotatestarted).toBe('ok'); + expect(rotated).toBe('ok'); + expect(rotateended).toBe('ok'); + done(); + }); + + test('cancels in-progress easing', () => { + camera.panTo([3, 4]); + expect(camera.isEasing()).toBeTruthy(); + camera.setBearing(6); + expect(!camera.isEasing()).toBeTruthy(); + }); +}); + +describe('#setPadding', () => { + test('sets padding', () => { + const camera = createCamera(); + const padding = { left: 300, top: 100, right: 50, bottom: 10 }; + camera.setPadding(padding); + expect(camera.getPadding()).toEqual(padding); + }); + + test('existing padding is retained if no new values are passed in', () => { + const camera = createCamera(); + const padding = { left: 300, top: 100, right: 50, bottom: 10 }; + camera.setPadding(padding); + camera.setPadding({}); + + const currentPadding = camera.getPadding(); + expect(currentPadding).toEqual(padding); + }); + + test("doesn't change padding thats already present if new value isn't passed in", () => { + const camera = createCamera(); + const padding = { left: 300, top: 100, right: 50, bottom: 10 }; + camera.setPadding(padding); + const padding1 = { right: 100 }; + camera.setPadding(padding1); + + const currentPadding = camera.getPadding(); + expect(currentPadding.left).toBe(padding.left); + expect(currentPadding.top).toBe(padding.top); + // padding1 here + expect(currentPadding.right).toBe(padding1.right); + expect(currentPadding.bottom).toBe(padding.bottom); + }); +}); + +describe('#panBy', () => { + test('pans by specified amount', () => { + const camera = createCamera(); + camera.panBy([100, 0], { duration: 0 }); + expect(fixedLngLat(camera.getCenter())).toEqual({ lng: 70.3125, lat: 0 }); + }); + + test('pans relative to viewport on a rotated camera', () => { + const camera = createCamera({ bearing: 180 }); + camera.panBy([100, 0], { duration: 0 }); + expect(fixedLngLat(camera.getCenter())).toEqual({ lng: -70.3125, lat: 0 }); + }); + + test('emits move events, preserving eventData', (done) => { + const camera = createCamera(); + let started, moved; + const eventData = { data: 'ok' }; + + camera + .on('movestart', (d) => { + started = d.data; + }) + .on('move', (d) => { + moved = d.data; + }) + .on('moveend', (d) => { + expect(started).toBe('ok'); + expect(moved).toBe('ok'); + expect(d.data).toBe('ok'); + done(); + }); + + camera.panBy([100, 0], { duration: 0 }, eventData); + }); + + test('suppresses movestart if noMoveStart option is true', (done) => { + const camera = createCamera(); + let started; + + // fire once in advance to satisfy assertions that moveend only comes after movestart + camera.fire('movestart'); + + camera + .on('movestart', () => { + started = true; + }) + .on('moveend', () => { + expect(!started).toBeTruthy(); + done(); + }); + + camera.panBy([100, 0], { duration: 0, noMoveStart: true }); + }); +}); + +describe('#panTo', () => { + test('pans to specified location', () => { + const camera = createCamera(); + camera.panTo([100, 0], { duration: 0 }); + expect(camera.getCenter()).toEqual({ lng: 100, lat: 0 }); + }); + + test('throws on invalid center argument', () => { + const camera = createCamera(); + expect(() => { + camera.panTo({ center: 1 }); + }).toThrow(Error); + }); + + test('pans with specified offset', () => { + const camera = createCamera(); + camera.panTo([100, 0], { offset: [100, 0], duration: 0 }); + expect(fixedLngLat(camera.getCenter())).toEqual({ lng: 29.6875, lat: 0 }); + }); + + test('pans with specified offset relative to viewport on a rotated camera', () => { + const camera = createCamera({ bearing: 180 }); + camera.panTo([100, 0], { offset: [100, 0], duration: 0 }); + expect(fixedLngLat(camera.getCenter())).toEqual({ lng: 170.3125, lat: 0 }); + }); + + test('emits move events, preserving eventData', (done) => { + const camera = createCamera(); + let started, moved; + const eventData = { data: 'ok' }; + + camera + .on('movestart', (d) => { + started = d.data; + }) + .on('move', (d) => { + moved = d.data; + }) + .on('moveend', (d) => { + expect(started).toBe('ok'); + expect(moved).toBe('ok'); + expect(d.data).toBe('ok'); + done(); + }); + + camera.panTo([100, 0], { duration: 0 }, eventData); + }); + + test('suppresses movestart if noMoveStart option is true', (done) => { + const camera = createCamera(); + let started; + + // fire once in advance to satisfy assertions that moveend only comes after movestart + camera.fire('movestart'); + + camera + .on('movestart', () => { + started = true; + }) + .on('moveend', () => { + expect(!started).toBeTruthy(); + done(); + }); + + camera.panTo([100, 0], { duration: 0, noMoveStart: true }); + }); +}); + +describe('#zoomTo', () => { + test('zooms to specified level', () => { + const camera = createCamera(); + camera.zoomTo(3.2, { duration: 0 }); + expect(camera.getZoom()).toBe(3.2); + }); + + test('zooms around specified location', () => { + const camera = createCamera(); + camera.zoomTo(3.2, { around: [5, 0], duration: 0 }); + expect(camera.getZoom()).toBe(3.2); + expect(fixedLngLat(camera.getCenter())).toEqual( + fixedLngLat({ lng: 4.455905897939886, lat: 0 }), + ); + }); + + test('zooms with specified offset', () => { + const camera = createCamera(); + camera.zoomTo(3.2, { offset: [100, 0], duration: 0 }); + expect(camera.getZoom()).toBe(3.2); + expect(fixedLngLat(camera.getCenter())).toEqual( + fixedLngLat({ lng: 62.66117668978015, lat: 0 }), + ); + }); + + test('zooms with specified offset relative to viewport on a rotated camera', () => { + const camera = createCamera({ bearing: 180 }); + camera.zoomTo(3.2, { offset: [100, 0], duration: 0 }); + expect(camera.getZoom()).toBe(3.2); + expect(fixedLngLat(camera.getCenter())).toEqual( + fixedLngLat({ lng: -62.66117668978012, lat: 0 }), + ); + }); + + test('emits move and zoom events, preserving eventData', (done) => { + const camera = createCamera(); + let movestarted, moved, zoomstarted, zoomed; + const eventData = { data: 'ok' }; + + expect.assertions(6); + + camera + .on('movestart', (d) => { + movestarted = d.data; + }) + .on('move', (d) => { + moved = d.data; + }) + .on('moveend', (d) => { + expect(movestarted).toBe('ok'); + expect(moved).toBe('ok'); + expect(d.data).toBe('ok'); + }); + + camera + .on('zoomstart', (d) => { + zoomstarted = d.data; + }) + .on('zoom', (d) => { + zoomed = d.data; + }) + .on('zoomend', (d) => { + expect(zoomstarted).toBe('ok'); + expect(zoomed).toBe('ok'); + expect(d.data).toBe('ok'); + }); + + camera.zoomTo(5, { duration: 0 }, eventData); + done(); + }); +}); + +describe('#rotateTo', () => { + test('rotates to specified bearing', () => { + const camera = createCamera(); + camera.rotateTo(90, { duration: 0 }); + expect(camera.getBearing()).toBe(90); + }); + + test('rotates around specified location', () => { + const camera = createCamera({ zoom: 3 }); + camera.rotateTo(90, { around: [5, 0], duration: 0 }); + expect(camera.getBearing()).toBe(90); + expect(fixedLngLat(camera.getCenter())).toEqual( + fixedLngLat({ lng: 4.999999999999972, lat: 4.993665859353271 }), + ); + }); + + test('rotates around specified location, constrained to fit the view', () => { + const camera = createCamera({ zoom: 0 }); + camera.rotateTo(90, { around: [5, 0], duration: 0 }); + expect(camera.getBearing()).toBe(90); + expect(fixedLngLat(camera.getCenter())).toEqual( + fixedLngLat({ lng: 4.999999999999972, lat: 0.000002552471840999715 }), + ); + }); + + test('rotates with specified offset', () => { + const camera = createCamera({ zoom: 1 }); + camera.rotateTo(90, { offset: [200, 0], duration: 0 }); + expect(camera.getBearing()).toBe(90); + expect(fixedLngLat(camera.getCenter())).toEqual( + fixedLngLat({ lng: 70.3125, lat: 57.3265212252 }), + ); + }); + + test('rotates with specified offset, constrained to fit the view', () => { + const camera = createCamera({ zoom: 0 }); + camera.rotateTo(90, { offset: [100, 0], duration: 0 }); + expect(camera.getBearing()).toBe(90); + expect(fixedLngLat(camera.getCenter())).toEqual( + fixedLngLat({ lng: 70.3125, lat: 0.000002552471840999715 }), + ); + }); + + test('rotates with specified offset relative to viewport on a rotated camera', () => { + const camera = createCamera({ bearing: 180, zoom: 1 }); + camera.rotateTo(90, { offset: [200, 0], duration: 0 }); + expect(camera.getBearing()).toBe(90); + expect(fixedLngLat(camera.getCenter())).toEqual( + fixedLngLat({ lng: -70.3125, lat: 57.3265212252 }), + ); + }); + + test('emits move and rotate events, preserving eventData', (done) => { + const camera = createCamera(); + let movestarted, moved, rotatestarted, rotated; + const eventData = { data: 'ok' }; + + expect.assertions(6); + + camera + .on('movestart', (d) => { + movestarted = d.data; + }) + .on('move', (d) => { + moved = d.data; + }) + .on('moveend', (d) => { + expect(movestarted).toBe('ok'); + expect(moved).toBe('ok'); + expect(d.data).toBe('ok'); + }); + + camera + .on('rotatestart', (d) => { + rotatestarted = d.data; + }) + .on('rotate', (d) => { + rotated = d.data; + }) + .on('rotateend', (d) => { + expect(rotatestarted).toBe('ok'); + expect(rotated).toBe('ok'); + expect(d.data).toBe('ok'); + }); + + camera.rotateTo(90, { duration: 0 }, eventData); + done(); + }); +}); + +describe('#easeTo', () => { + test('pans to specified location', () => { + const camera = createCamera(); + camera.easeTo({ center: [100, 0], duration: 0 }); + expect(camera.getCenter()).toEqual({ lng: 100, lat: 0 }); + }); + + test('zooms to specified level', () => { + const camera = createCamera(); + camera.easeTo({ zoom: 3.2, duration: 0 }); + expect(camera.getZoom()).toBe(3.2); + }); + + test('rotates to specified bearing', () => { + const camera = createCamera(); + camera.easeTo({ bearing: 90, duration: 0 }); + expect(camera.getBearing()).toBe(90); + }); + + test('pitches to specified pitch', () => { + const camera = createCamera(); + camera.easeTo({ pitch: 45, duration: 0 }); + expect(camera.getPitch()).toBe(45); + }); + + test('pans and zooms', () => { + const camera = createCamera(); + camera.easeTo({ center: [100, 0], zoom: 3.2, duration: 0 }); + expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat({ lng: 100, lat: 0 })); + expect(camera.getZoom()).toBe(3.2); + }); + + test('zooms around a point', () => { + const camera = createCamera(); + camera.easeTo({ around: [100, 0], zoom: 3, duration: 0 }); + expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat({ lng: 87.5, lat: 0 })); + expect(camera.getZoom()).toBe(3); + }); + + test('pans and rotates', () => { + const camera = createCamera(); + camera.easeTo({ center: [100, 0], bearing: 90, duration: 0 }); + expect(camera.getCenter()).toEqual({ lng: 100, lat: 0 }); + expect(camera.getBearing()).toBe(90); + }); + + test('zooms and rotates', () => { + const camera = createCamera(); + camera.easeTo({ zoom: 3.2, bearing: 90, duration: 0 }); + expect(camera.getZoom()).toBe(3.2); + expect(camera.getBearing()).toBe(90); + }); + + test('pans, zooms, and rotates', () => { + const camera = createCamera({ bearing: -90 }); + camera.easeTo({ center: [100, 0], zoom: 3.2, bearing: 90, duration: 0 }); + expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat({ lng: 100, lat: 0 })); + expect(camera.getZoom()).toBe(3.2); + expect(camera.getBearing()).toBe(90); + }); + + test('noop', () => { + const camera = createCamera(); + camera.easeTo({ duration: 0 }); + expect(fixedLngLat(camera.getCenter())).toEqual({ lng: 0, lat: 0 }); + expect(camera.getZoom()).toBe(0); + expect(camera.getBearing()).toBeCloseTo(0); + }); + + test('noop with offset', () => { + const camera = createCamera(); + camera.easeTo({ offset: [100, 0], duration: 0 }); + expect(fixedLngLat(camera.getCenter())).toEqual({ lng: 0, lat: 0 }); + expect(camera.getZoom()).toBe(0); + expect(camera.getBearing()).toBeCloseTo(0); + }); + + test('pans with specified offset', () => { + const camera = createCamera(); + camera.easeTo({ center: [100, 0], offset: [100, 0], duration: 0 }); + expect(fixedLngLat(camera.getCenter())).toEqual({ lng: 29.6875, lat: 0 }); + }); + + test('pans with specified offset relative to viewport on a rotated camera', () => { + const camera = createCamera({ bearing: 180 }); + camera.easeTo({ center: [100, 0], offset: [100, 0], duration: 0 }); + expect(fixedLngLat(camera.getCenter())).toEqual({ lng: 170.3125, lat: 0 }); + }); + + test('zooms with specified offset', () => { + const camera = createCamera(); + camera.easeTo({ zoom: 3.2, offset: [100, 0], duration: 0 }); + expect(camera.getZoom()).toBe(3.2); + expect(fixedLngLat(camera.getCenter())).toEqual( + fixedLngLat({ lng: 62.66117668978015, lat: 0 }), + ); + }); + + test('zooms with specified offset relative to viewport on a rotated camera', () => { + const camera = createCamera({ bearing: 180 }); + camera.easeTo({ zoom: 3.2, offset: [100, 0], duration: 0 }); + expect(camera.getZoom()).toBe(3.2); + expect(fixedLngLat(camera.getCenter())).toEqual( + fixedLngLat({ lng: -62.66117668978012, lat: 0 }), + ); + }); + + test('rotates with specified offset', () => { + const camera = createCamera(); + camera.easeTo({ bearing: 90, offset: [100, 0], duration: 0 }); + expect(camera.getBearing()).toBe(90); + expect(fixedLngLat(camera.getCenter())).toEqual( + fixedLngLat({ lng: 70.3125, lat: 0.000002552471840999715 }), + ); + }); + + test('rotates with specified offset relative to viewport on a rotated camera', () => { + const camera = createCamera({ bearing: 180 }); + camera.easeTo({ bearing: 90, offset: [100, 0], duration: 0 }); + expect(camera.getBearing()).toBe(90); + expect(fixedLngLat(camera.getCenter())).toEqual( + fixedLngLat({ lng: -70.3125, lat: 0.000002552471840999715 }), + ); + }); + + test('emits move, zoom, rotate, and pitch events, preserving eventData', (done) => { + const camera = createCamera(); + let movestarted, moved, zoomstarted, zoomed, rotatestarted, rotated, pitchstarted, pitched; + const eventData = { data: 'ok' }; + + expect.assertions(18); + + camera + .on('movestart', (d) => { + movestarted = d.data; + }) + .on('move', (d) => { + moved = d.data; + }) + .on('moveend', (d) => { + expect(camera._zooming).toBeFalsy(); + expect(camera._panning).toBeFalsy(); + expect(camera._rotating).toBeFalsy(); + + expect(movestarted).toBe('ok'); + expect(moved).toBe('ok'); + expect(zoomed).toBe('ok'); + expect(rotated).toBe('ok'); + expect(pitched).toBe('ok'); + expect(d.data).toBe('ok'); + }); + + camera + .on('zoomstart', (d) => { + zoomstarted = d.data; + }) + .on('zoom', (d) => { + zoomed = d.data; + }) + .on('zoomend', (d) => { + expect(zoomstarted).toBe('ok'); + expect(zoomed).toBe('ok'); + expect(d.data).toBe('ok'); + }); + + camera + .on('rotatestart', (d) => { + rotatestarted = d.data; + }) + .on('rotate', (d) => { + rotated = d.data; + }) + .on('rotateend', (d) => { + expect(rotatestarted).toBe('ok'); + expect(rotated).toBe('ok'); + expect(d.data).toBe('ok'); + }); + + camera + .on('pitchstart', (d) => { + pitchstarted = d.data; + }) + .on('pitch', (d) => { + pitched = d.data; + }) + .on('pitchend', (d) => { + expect(pitchstarted).toBe('ok'); + expect(pitched).toBe('ok'); + expect(d.data).toBe('ok'); + }); + + camera.easeTo({ center: [100, 0], zoom: 3.2, bearing: 90, duration: 0, pitch: 45 }, eventData); + done(); + }); + + test('does not emit zoom events if not zooming', (done) => { + const camera = createCamera(); + + camera + .on('zoomstart', () => { + done('zoomstart failed'); + }) + .on('zoom', () => { + done('zoom failed'); + }) + .on('zoomend', () => { + done('zoomend failed'); + }) + .on('moveend', () => { + done(); + }); + + camera.easeTo({ center: [100, 0], duration: 0 }); + }); + + test('stops existing ease', () => { + const camera = createCamera(); + camera.easeTo({ center: [200, 0], duration: 100 }); + camera.easeTo({ center: [100, 0], duration: 0 }); + expect(camera.getCenter()).toEqual({ lng: 100, lat: 0 }); + }); + + test('can be called from within a moveend event handler', (done) => { + const camera = createCamera(); + const stub = jest.spyOn(browser, 'now'); + + stub.mockImplementation(() => 0); + camera.easeTo({ center: [100, 0], duration: 10 }); + + camera.once('moveend', () => { + camera.easeTo({ center: [200, 0], duration: 10 }); + camera.once('moveend', () => { + camera.easeTo({ center: [300, 0], duration: 10 }); + camera.once('moveend', () => { + done(); + }); + + setTimeout(() => { + stub.mockImplementation(() => 30); + camera.simulateFrame(); + }, 0); + }); + + // setTimeout to avoid a synchronous callback + setTimeout(() => { + stub.mockImplementation(() => 20); + camera.simulateFrame(); + }, 0); + }); + + // setTimeout to avoid a synchronous callback + setTimeout(() => { + stub.mockImplementation(() => 10); + camera.simulateFrame(); + }, 0); + }); + + test('pans eastward across the antimeridian', (done) => { + const camera = createCamera(); + const stub = jest.spyOn(browser, 'now'); + + camera.setCenter([170, 0]); + let crossedAntimeridian; + + camera.on('move', () => { + if (camera.getCenter().lng > 170) { + crossedAntimeridian = true; + } + }); + + camera.on('moveend', () => { + expect(crossedAntimeridian).toBeTruthy(); + done(); + }); + + stub.mockImplementation(() => 0); + camera.easeTo({ center: [-170, 0], duration: 10 }); + + setTimeout(() => { + stub.mockImplementation(() => 1); + camera.simulateFrame(); + + setTimeout(() => { + stub.mockImplementation(() => 10); + camera.simulateFrame(); + }, 0); + }, 0); + }); + + test('does not pan eastward across the antimeridian on a single-globe mercator map', (done) => { + const camera = createCamera({ renderWorldCopies: false, zoom: 2 }); + camera.setCenter([170, 0]); + const initialLng = camera.getCenter().lng; + camera.on('moveend', () => { + expect(camera.getCenter().lng).toBeCloseTo(initialLng, 0); + done(); + }); + camera.easeTo({ center: [210, 0], duration: 0 }); + }); + + test('pans westward across the antimeridian', (done) => { + const camera = createCamera(); + const stub = jest.spyOn(browser, 'now'); + + camera.setCenter([-170, 0]); + let crossedAntimeridian; + + camera.on('move', () => { + if (camera.getCenter().lng < -170) { + crossedAntimeridian = true; + } + }); + + camera.on('moveend', () => { + expect(crossedAntimeridian).toBeTruthy(); + done(); + }); + + stub.mockImplementation(() => 0); + camera.easeTo({ center: [170, 0], duration: 10 }); + + setTimeout(() => { + stub.mockImplementation(() => 1); + camera.simulateFrame(); + + setTimeout(() => { + stub.mockImplementation(() => 10); + camera.simulateFrame(); + }, 0); + }, 0); + }); + + test('does not pan westward across the antimeridian on a single-globe mercator map', (done) => { + const camera = createCamera({ renderWorldCopies: false, zoom: 2 }); + camera.setCenter([-170, 0]); + const initialLng = camera.getCenter().lng; + camera.on('moveend', () => { + expect(camera.getCenter().lng).toBeCloseTo(initialLng, 0); + done(); + }); + camera.easeTo({ center: [-210, 0], duration: 0 }); + }); + + test('animation occurs when prefers-reduced-motion: reduce is set but overridden by essential: true', (done) => { + const camera = createCamera(); + Object.defineProperty(browser, 'prefersReducedMotion', { value: true }); + const stubNow = jest.spyOn(browser, 'now'); + + // camera transition expected to take in this range when prefersReducedMotion is set and essential: true, + // when a duration of 200 is requested + const min = 100; + const max = 300; + + let startTime; + camera + .on('movestart', () => { + startTime = browser.now(); + }) + .on('moveend', () => { + const endTime = browser.now(); + const timeDiff = endTime - startTime; + expect(timeDiff >= min && timeDiff < max).toBeTruthy(); + done(); + }); + + setTimeout(() => { + stubNow.mockImplementation(() => 0); + camera.simulateFrame(); + + camera.easeTo({ center: [100, 0], zoom: 3.2, bearing: 90, duration: 200, essential: true }); + + setTimeout(() => { + stubNow.mockImplementation(() => 200); + camera.simulateFrame(); + }, 0); + }, 0); + }); + + test('duration is 0 when prefers-reduced-motion: reduce is set', (done) => { + const camera = createCamera(); + Object.defineProperty(browser, 'prefersReducedMotion', { value: true }); + assertTransitionTime(done, camera, 0, 10); + camera.easeTo({ center: [100, 0], zoom: 3.2, bearing: 90, duration: 1000 }); + }); + + test('jumpTo on("move") during easeTo with zoom, pitch, etc', (done) => { + const camera = createCamera(); + + camera.on('moveend', (e: Event & { done?: true }) => { + if ('done' in e) { + setTimeout(() => { + done(); + }, 50); + } + }); + + camera.easeTo({ zoom: 20, bearing: 90, pitch: 60, duration: 500 }, { done: true }); + camera.once('move', () => { + camera.jumpTo({ pitch: 40 }); + }); + + camera.simulateFrame(); + camera.simulateFrame(); + }); + + test('jumpTo on("zoom") during easeTo', (done) => { + const camera = createCamera(); + + camera.on('moveend', (e: Event & { done?: true }) => { + if ('done' in e) { + setTimeout(() => { + done(); + }, 50); + } + }); + + camera.easeTo({ zoom: 20, duration: 500 }, { done: true }); + camera.once('zoom', () => { + camera.jumpTo({ pitch: 40 }); + }); + + camera.simulateFrame(); + camera.simulateFrame(); + }); + + test('jumpTo on("pitch") during easeTo', (done) => { + const camera = createCamera(); + + camera.on('moveend', (e: Event & { done?: true }) => { + if ('done' in e) { + setTimeout(() => { + done(); + }, 50); + } + }); + + camera.easeTo({ pitch: 60, duration: 500 }, { done: true }); + camera.once('pitch', () => { + camera.jumpTo({ pitch: 40 }); + }); + + camera.simulateFrame(); + camera.simulateFrame(); + }); + + test('jumpTo on("rotate") during easeTo', (done) => { + const camera = createCamera(); + + camera.on('moveend', (e: Event & { done?: true }) => { + if ('done' in e) { + setTimeout(() => { + done(); + }, 50); + } + }); + + camera.easeTo({ bearing: 90, duration: 500 }, { done: true }); + camera.once('rotate', () => { + camera.jumpTo({ pitch: 40 }); + }); + + camera.simulateFrame(); + camera.simulateFrame(); + }); +}); + +describe('#flyTo', () => { + test('pans to specified location', () => { + const camera = createCamera(); + camera.flyTo({ center: [100, 0], animate: false }); + expect(fixedLngLat(camera.getCenter())).toEqual({ lng: 100, lat: 0 }); + }); + + test('throws on invalid center argument', () => { + const camera = createCamera(); + expect(() => { + camera.flyTo({ center: 1 }); + }).toThrow(Error); + }); + + test('does not throw when cameras current zoom is sufficiently greater than passed zoom option', () => { + const camera = createCamera({ zoom: 22, center: [0, 0] }); + expect(() => camera.flyTo({ zoom: 10, center: [0, 0] })).not.toThrow(); + }); + + test('does not throw when cameras current zoom is above maxzoom and an offset creates infinite zoom out factor', () => { + const transform = new Transform(0, 20.9999, 0, 60, true); + transform.resize(512, 512); + const camera = attachSimulateFrame(new CameraMock(transform, {} as any)).jumpTo({ + zoom: 21, + center: [0, 0], + }); + camera._update = () => {}; + expect(() => camera.flyTo({ zoom: 7.5, center: [0, 0], offset: [0, 70] })).not.toThrow(); + }); + + test('zooms to specified level', () => { + const camera = createCamera(); + camera.flyTo({ zoom: 3.2, animate: false }); + expect(fixedNum(camera.getZoom())).toBe(3.2); + }); + + test('zooms to integer level without floating point errors', () => { + const camera = createCamera({ zoom: 0.6 }); + camera.flyTo({ zoom: 2, animate: false }); + expect(camera.getZoom()).toBe(2); + }); + + test('Zoom out from the same position to the same position with animation', (done) => { + const pos = { lng: 0, lat: 0 }; + const camera = createCamera({ zoom: 20, center: pos }); + const stub = jest.spyOn(browser, 'now'); + + camera.once('zoomend', () => { + expect(fixedLngLat(camera.getCenter())).toEqual(fixedLngLat(pos)); + expect(camera.getZoom()).toBe(19); + done(); + }); + + stub.mockImplementation(() => 0); + camera.flyTo({ zoom: 19, center: pos, duration: 2 }); + + stub.mockImplementation(() => 3); + camera.simulateFrame(); + }); + + test('rotates to specified bearing', () => { + const camera = createCamera(); + camera.flyTo({ bearing: 90, animate: false }); + expect(camera.getBearing()).toBe(90); + }); + + test('tilts to specified pitch', () => { + const camera = createCamera(); + camera.flyTo({ pitch: 45, animate: false }); + expect(camera.getPitch()).toBe(45); + }); + + test('pans and zooms', () => { + const camera = createCamera(); + camera.flyTo({ center: [100, 0], zoom: 3.2, animate: false }); + expect(fixedLngLat(camera.getCenter())).toEqual({ lng: 100, lat: 0 }); + expect(fixedNum(camera.getZoom())).toBe(3.2); + }); + + test('pans and rotates', () => { + const camera = createCamera(); + camera.flyTo({ center: [100, 0], bearing: 90, animate: false }); + expect(fixedLngLat(camera.getCenter())).toEqual({ lng: 100, lat: 0 }); + expect(camera.getBearing()).toBe(90); + }); + + test('zooms and rotates', () => { + const camera = createCamera(); + camera.flyTo({ zoom: 3.2, bearing: 90, animate: false }); + expect(fixedNum(camera.getZoom())).toBe(3.2); + expect(camera.getBearing()).toBe(90); + }); + + test('pans, zooms, and rotates', () => { + const camera = createCamera(); + camera.flyTo({ center: [100, 0], zoom: 3.2, bearing: 90, duration: 0, animate: false }); + expect(fixedLngLat(camera.getCenter())).toEqual({ lng: 100, lat: 0 }); + expect(fixedNum(camera.getZoom())).toBe(3.2); + expect(camera.getBearing()).toBe(90); + }); + + test('noop', () => { + const camera = createCamera(); + camera.flyTo({ animate: false }); + expect(fixedLngLat(camera.getCenter())).toEqual({ lng: 0, lat: 0 }); + expect(camera.getZoom()).toBe(0); + expect(camera.getBearing()).toBeCloseTo(0); + }); + + test('noop with offset', () => { + const camera = createCamera(); + camera.flyTo({ offset: [100, 0], animate: false }); + expect(fixedLngLat(camera.getCenter())).toEqual({ lng: 0, lat: 0 }); + expect(camera.getZoom()).toBe(0); + expect(camera.getBearing()).toBeCloseTo(0); + }); + + test('pans with specified offset', () => { + const camera = createCamera(); + camera.flyTo({ center: [100, 0], offset: [100, 0], animate: false }); + expect(fixedLngLat(camera.getCenter())).toEqual({ lng: 29.6875, lat: 0 }); + }); + + test('pans with specified offset relative to viewport on a rotated camera', () => { + const camera = createCamera({ bearing: 180 }); + camera.easeTo({ center: [100, 0], offset: [100, 0], animate: false }); + expect(fixedLngLat(camera.getCenter())).toEqual({ lng: 170.3125, lat: 0 }); + }); + + test('emits move, zoom, rotate, and pitch events, preserving eventData', (done) => { + expect.assertions(18); + + const camera = createCamera(); + let movestarted, moved, zoomstarted, zoomed, rotatestarted, rotated, pitchstarted, pitched; + const eventData = { data: 'ok' }; + + camera + .on('movestart', (d) => { + movestarted = d.data; + }) + .on('move', (d) => { + moved = d.data; + }) + .on('rotate', (d) => { + rotated = d.data; + }) + .on('pitch', (d) => { + pitched = d.data; + }) + .on('moveend', (d) => { + expect(camera._zooming).toBeFalsy(); + expect(camera._panning).toBeFalsy(); + expect(camera._rotating).toBeFalsy(); + + expect(movestarted).toBe('ok'); + expect(moved).toBe('ok'); + expect(zoomed).toBe('ok'); + expect(rotated).toBe('ok'); + expect(pitched).toBe('ok'); + expect(d.data).toBe('ok'); + }); + + camera + .on('zoomstart', (d) => { + zoomstarted = d.data; + }) + .on('zoom', (d) => { + zoomed = d.data; + }) + .on('zoomend', (d) => { + expect(zoomstarted).toBe('ok'); + expect(zoomed).toBe('ok'); + expect(d.data).toBe('ok'); + }); + + camera + .on('rotatestart', (d) => { + rotatestarted = d.data; + }) + .on('rotate', (d) => { + rotated = d.data; + }) + .on('rotateend', (d) => { + expect(rotatestarted).toBe('ok'); + expect(rotated).toBe('ok'); + expect(d.data).toBe('ok'); + }); + + camera + .on('pitchstart', (d) => { + pitchstarted = d.data; + }) + .on('pitch', (d) => { + pitched = d.data; + }) + .on('pitchend', (d) => { + expect(pitchstarted).toBe('ok'); + expect(pitched).toBe('ok'); + expect(d.data).toBe('ok'); + }); + + camera.flyTo( + { center: [100, 0], zoom: 3.2, bearing: 90, duration: 0, pitch: 45, animate: false }, + eventData, + ); + done(); + }); + + test('for short flights, emits (solely) move events, preserving eventData', (done) => { + //As I type this, the code path for guiding super-short flights is (and will probably remain) different. + //As such; it deserves a separate test case. This test case flies the map from A to A. + const camera = createCamera({ center: [100, 0] }); + let movestarted, + moved, + zoomstarted, + zoomed, + zoomended, + rotatestarted, + rotated, + rotateended, + pitchstarted, + pitched, + pitchended; + const eventData = { data: 'ok' }; + + camera + .on('movestart', (d) => { + movestarted = d.data; + }) + .on('move', (d) => { + moved = d.data; + }) + .on('zoomstart', (d) => { + zoomstarted = d.data; + }) + .on('zoom', (d) => { + zoomed = d.data; + }) + .on('zoomend', (d) => { + zoomended = d.data; + }) + .on('rotatestart', (d) => { + rotatestarted = d.data; + }) + .on('rotate', (d) => { + rotated = d.data; + }) + .on('rotateend', (d) => { + rotateended = d.data; + }) + .on('pitchstart', (d) => { + pitchstarted = d.data; + }) + .on('pitch', (d) => { + pitched = d.data; + }) + .on('pitchend', (d) => { + pitchended = d.data; + }) + .on('moveend', (d) => { + expect(camera._zooming).toBeFalsy(); + expect(camera._panning).toBeFalsy(); + expect(camera._rotating).toBeFalsy(); + + expect(movestarted).toBe('ok'); + expect(moved).toBe('ok'); + expect(zoomstarted).toBeUndefined(); + expect(zoomed).toBeUndefined(); + expect(zoomended).toBeUndefined(); + expect(rotatestarted).toBeUndefined(); + expect(rotated).toBeUndefined(); + expect(rotateended).toBeUndefined(); + expect(pitched).toBeUndefined(); + expect(pitchstarted).toBeUndefined(); + expect(pitchended).toBeUndefined(); + expect(d.data).toBe('ok'); + done(); + }); + + const stub = jest.spyOn(browser, 'now'); + stub.mockImplementation(() => 0); + + camera.flyTo({ center: [100, 0], duration: 10 }, eventData); + + setTimeout(() => { + stub.mockImplementation(() => 1); + camera.simulateFrame(); + + setTimeout(() => { + stub.mockImplementation(() => 10); + camera.simulateFrame(); + }, 0); + }, 0); + }); + + test('stops existing ease', (done) => { + const camera = createCamera(); + camera.flyTo({ center: [200, 0], duration: 100 }); + camera.flyTo({ center: [100, 0], duration: 0 }); + expect(fixedLngLat(camera.getCenter())).toEqual({ lng: 100, lat: 0 }); + done(); + }); + + test('can be called from within a moveend event handler', (done) => { + const camera = createCamera(); + const stub = jest.spyOn(browser, 'now'); + stub.mockImplementation(() => 0); + + camera.flyTo({ center: [100, 0], duration: 10 }); + camera.once('moveend', () => { + camera.flyTo({ center: [200, 0], duration: 10 }); + camera.once('moveend', () => { + camera.flyTo({ center: [300, 0], duration: 10 }); + camera.once('moveend', () => { + done(); + }); + }); + }); + + setTimeout(() => { + stub.mockImplementation(() => 10); + camera.simulateFrame(); + + setTimeout(() => { + stub.mockImplementation(() => 20); + camera.simulateFrame(); + + setTimeout(() => { + stub.mockImplementation(() => 30); + camera.simulateFrame(); + }, 0); + }, 0); + }, 0); + }); + + test('ascends', (done) => { + const camera = createCamera(); + camera.setZoom(18); + let ascended; + + camera.on('zoom', () => { + if (camera.getZoom() < 18) { + ascended = true; + } + }); + + camera.on('moveend', () => { + expect(ascended).toBeTruthy(); + done(); + }); + + const stub = jest.spyOn(browser, 'now'); + stub.mockImplementation(() => 0); + + camera.flyTo({ center: [100, 0], zoom: 18, duration: 10 }); + + setTimeout(() => { + stub.mockImplementation(() => 1); + camera.simulateFrame(); + + setTimeout(() => { + stub.mockImplementation(() => 10); + camera.simulateFrame(); + }, 0); + }, 0); + }); + + test('pans eastward across the prime meridian', (done) => { + const camera = createCamera(); + const stub = jest.spyOn(browser, 'now'); + + camera.setCenter([-10, 0]); + let crossedPrimeMeridian; + + camera.on('move', () => { + if (Math.abs(camera.getCenter().lng) < 10) { + crossedPrimeMeridian = true; + } + }); + + camera.on('moveend', () => { + expect(crossedPrimeMeridian).toBeTruthy(); + done(); + }); + + stub.mockImplementation(() => 0); + camera.flyTo({ center: [10, 0], duration: 20 }); + + setTimeout(() => { + stub.mockImplementation(() => 1); + camera.simulateFrame(); + + setTimeout(() => { + stub.mockImplementation(() => 20); + camera.simulateFrame(); + }, 0); + }, 0); + }); + + test('pans westward across the prime meridian', (done) => { + const camera = createCamera(); + const stub = jest.spyOn(browser, 'now'); + + camera.setCenter([10, 0]); + let crossedPrimeMeridian; + + camera.on('move', () => { + if (Math.abs(camera.getCenter().lng) < 10) { + crossedPrimeMeridian = true; + } + }); + + camera.on('moveend', () => { + expect(crossedPrimeMeridian).toBeTruthy(); + done(); + }); + + stub.mockImplementation(() => 0); + camera.flyTo({ center: [-10, 0], duration: 20 }); + + setTimeout(() => { + stub.mockImplementation(() => 1); + camera.simulateFrame(); + + setTimeout(() => { + stub.mockImplementation(() => 20); + camera.simulateFrame(); + }, 0); + }, 0); + }); + + test('pans eastward across the antimeridian', (done) => { + const camera = createCamera(); + const stub = jest.spyOn(browser, 'now'); + + camera.setCenter([170, 0]); + let crossedAntimeridian; + + camera.on('move', () => { + if (camera.getCenter().lng > 170) { + crossedAntimeridian = true; + } + }); + + camera.on('moveend', () => { + expect(crossedAntimeridian).toBeTruthy(); + done(); + }); + + stub.mockImplementation(() => 0); + camera.flyTo({ center: [-170, 0], duration: 20 }); + + setTimeout(() => { + stub.mockImplementation(() => 1); + camera.simulateFrame(); + + setTimeout(() => { + stub.mockImplementation(() => 20); + camera.simulateFrame(); + }, 0); + }, 0); + }); + + test('pans westward across the antimeridian', (done) => { + const camera = createCamera(); + const stub = jest.spyOn(browser, 'now'); + + camera.setCenter([-170, 0]); + let crossedAntimeridian; + + camera.on('move', () => { + if (camera.getCenter().lng < -170) { + crossedAntimeridian = true; + } + }); + + camera.on('moveend', () => { + expect(crossedAntimeridian).toBeTruthy(); + done(); + }); + + stub.mockImplementation(() => 0); + camera.flyTo({ center: [170, 0], duration: 10 }); + + setTimeout(() => { + stub.mockImplementation(() => 1); + camera.simulateFrame(); + + setTimeout(() => { + stub.mockImplementation(() => 10); + camera.simulateFrame(); + }, 0); + }, 0); + }); + + test('does not pan eastward across the antimeridian if no world copies', (done) => { + const camera = createCamera({ renderWorldCopies: false }); + const stub = jest.spyOn(browser, 'now'); + + camera.setCenter([170, 0]); + let crossedAntimeridian; + + camera.on('move', () => { + if (camera.getCenter().lng > 170) { + crossedAntimeridian = true; + } + }); + + camera.on('moveend', () => { + expect(crossedAntimeridian).toBeFalsy(); + done(); + }); + + stub.mockImplementation(() => 0); + camera.flyTo({ center: [-170, 0], duration: 10 }); + + setTimeout(() => { + stub.mockImplementation(() => 1); + camera.simulateFrame(); + + setTimeout(() => { + stub.mockImplementation(() => 10); + camera.simulateFrame(); + }, 0); + }, 0); + }); + + test('does not pan westward across the antimeridian if no world copies', (done) => { + const camera = createCamera({ renderWorldCopies: false }); + const stub = jest.spyOn(browser, 'now'); + + camera.setCenter([-170, 0]); + let crossedAntimeridian; + + camera.on('move', () => { + if (fixedLngLat(camera.getCenter(), 10).lng < -170) { + crossedAntimeridian = true; + } + }); + + camera.on('moveend', () => { + expect(crossedAntimeridian).toBeFalsy(); + done(); + }); + + stub.mockImplementation(() => 0); + camera.flyTo({ center: [170, 0], duration: 10 }); + + setTimeout(() => { + stub.mockImplementation(() => 1); + camera.simulateFrame(); + + setTimeout(() => { + stub.mockImplementation(() => 10); + camera.simulateFrame(); + }, 0); + }, 0); + }); + + test('jumps back to world 0 when crossing the antimeridian', (done) => { + const camera = createCamera(); + const stub = jest.spyOn(browser, 'now'); + + camera.setCenter([-170, 0]); + + let leftWorld0 = false; + + camera.on('move', () => { + leftWorld0 = leftWorld0 || camera.getCenter().lng < -180; + }); + + camera.on('moveend', () => { + expect(leftWorld0).toBeFalsy(); + done(); + }); + + stub.mockImplementation(() => 0); + camera.flyTo({ center: [170, 0], duration: 10 }); + + setTimeout(() => { + stub.mockImplementation(() => 1); + camera.simulateFrame(); + + setTimeout(() => { + stub.mockImplementation(() => 10); + camera.simulateFrame(); + }, 0); + }, 0); + }); + + test('peaks at the specified zoom level', (done) => { + const camera = createCamera({ zoom: 20 }); + const stub = jest.spyOn(browser, 'now'); + + const minZoom = 1; + let zoomed = false; + + camera.on('zoom', () => { + const zoom = camera.getZoom(); + if (zoom < 1) { + fail(`${zoom} should be >= ${minZoom} during flyTo`); + } + + if (camera.getZoom() < minZoom + 1) { + zoomed = true; + } + }); + + camera.on('moveend', () => { + expect(zoomed).toBeTruthy(); + done(); + }); + + stub.mockImplementation(() => 0); + camera.flyTo({ center: [1, 0], zoom: 20, minZoom, duration: 10 }); + + setTimeout(() => { + stub.mockImplementation(() => 3); + camera.simulateFrame(); + + setTimeout(() => { + stub.mockImplementation(() => 10); + camera.simulateFrame(); + }, 0); + }, 0); + }); + + test("respects transform's maxZoom", (done) => { + const transform = new Transform(2, 10, 0, 60, false); + transform.resize(512, 512); + + const camera = attachSimulateFrame(new CameraMock(transform, {} as any)); + camera._update = () => {}; + + camera.on('moveend', () => { + expect(camera.getZoom()).toBeCloseTo(10); + const { lng, lat } = camera.getCenter(); + expect(lng).toBeCloseTo(12); + expect(lat).toBeCloseTo(34); + done(); + }); + + const stub = jest.spyOn(browser, 'now'); + stub.mockImplementation(() => 0); + camera.flyTo({ center: [12, 34], zoom: 30, duration: 10 }); + + setTimeout(() => { + stub.mockImplementation(() => 10); + camera.simulateFrame(); + }, 0); + }); + + test("respects transform's minZoom", (done) => { + const transform = new Transform(2, 10, 0, 60, false); + transform.resize(512, 512); + + const camera = attachSimulateFrame(new CameraMock(transform, {} as any)); + camera._update = () => {}; + + camera.on('moveend', () => { + expect(camera.getZoom()).toBeCloseTo(2); + const { lng, lat } = camera.getCenter(); + expect(lng).toBeCloseTo(12); + expect(lat).toBeCloseTo(34); + done(); + }); + + const stub = jest.spyOn(browser, 'now'); + stub.mockImplementation(() => 0); + camera.flyTo({ center: [12, 34], zoom: 1, duration: 10 }); + + setTimeout(() => { + stub.mockImplementation(() => 10); + camera.simulateFrame(); + }, 0); + }); + + test('resets duration to 0 if it exceeds maxDuration', (done) => { + let startTime, endTime, timeDiff; + const camera = createCamera({ center: [37.63454, 55.75868], zoom: 18 }); + + camera + .on('movestart', () => { + startTime = new Date(); + }) + .on('moveend', () => { + endTime = new Date(); + timeDiff = endTime - startTime; + expect(timeDiff).toBeLessThan(30); + done(); + }); + + camera.flyTo({ center: [-122.3998631, 37.7884307], maxDuration: 100 }); + }); + + test('flys instantly when prefers-reduce-motion:reduce is set', (done) => { + const camera = createCamera(); + Object.defineProperty(browser, 'prefersReducedMotion', { value: true }); + assertTransitionTime(done, camera, 0, 10); + camera.flyTo({ center: [100, 0], bearing: 90, animate: true }); + }); +}); + +describe('#isEasing', () => { + test('returns false when not easing', () => { + const camera = createCamera(); + expect(!camera.isEasing()).toBeTruthy(); + }); + + test('returns true when panning', () => { + const camera = createCamera(); + camera.panTo([100, 0], { duration: 1 }); + expect(camera.isEasing()).toBeTruthy(); + }); + + test('returns false when done panning', (done) => { + const camera = createCamera(); + camera.on('moveend', () => { + expect(!camera.isEasing()).toBeTruthy(); + done(); + }); + const stub = jest.spyOn(browser, 'now'); + stub.mockImplementation(() => 0); + camera.panTo([100, 0], { duration: 1 }); + setTimeout(() => { + stub.mockImplementation(() => 1); + camera.simulateFrame(); + }, 0); + }); + + test('returns true when zooming', () => { + const camera = createCamera(); + camera.zoomTo(3.2, { duration: 1 }); + + expect(camera.isEasing()).toBeTruthy(); + }); + + test('returns false when done zooming', (done) => { + const camera = createCamera(); + camera.on('moveend', () => { + expect(!camera.isEasing()).toBeTruthy(); + done(); + }); + const stub = jest.spyOn(browser, 'now'); + stub.mockImplementation(() => 0); + camera.zoomTo(3.2, { duration: 1 }); + setTimeout(() => { + stub.mockImplementation(() => 1); + camera.simulateFrame(); + }, 0); + }); + + test('returns true when rotating', () => { + const camera = createCamera(); + camera.rotateTo(90, { duration: 1 }); + expect(camera.isEasing()).toBeTruthy(); + }); + + test('returns false when done rotating', (done) => { + const camera = createCamera(); + camera.on('moveend', () => { + expect(!camera.isEasing()).toBeTruthy(); + done(); + }); + const stub = jest.spyOn(browser, 'now'); + stub.mockImplementation(() => 0); + camera.rotateTo(90, { duration: 1 }); + setTimeout(() => { + stub.mockImplementation(() => 1); + camera.simulateFrame(); + }, 0); + }); +}); + +describe('#stop', () => { + test('resets camera._zooming', () => { + const camera = createCamera(); + camera.zoomTo(3.2); + camera.stop(); + expect(!camera._zooming).toBeTruthy(); + }); + + test('resets camera._rotating', () => { + const camera = createCamera(); + camera.rotateTo(90); + camera.stop(); + expect(!camera._rotating).toBeTruthy(); + }); + + test('emits moveend if panning, preserving eventData', (done) => { + const camera = createCamera(); + const eventData = { data: 'ok' }; + + camera.on('moveend', (d) => { + expect(d.data).toBe('ok'); + done(); + }); + + camera.panTo([100, 0], {}, eventData); + camera.stop(); + }); + + test('emits moveend if zooming, preserving eventData', (done) => { + const camera = createCamera(); + const eventData = { data: 'ok' }; + + camera.on('moveend', (d) => { + expect(d.data).toBe('ok'); + done(); + }); + + camera.zoomTo(3.2, {}, eventData); + camera.stop(); + }); + + test('emits moveend if rotating, preserving eventData', (done) => { + const camera = createCamera(); + const eventData = { data: 'ok' }; + + camera.on('moveend', (d) => { + expect(d.data).toBe('ok'); + done(); + }); + + camera.rotateTo(90, {}, eventData); + camera.stop(); + }); + + test('does not emit moveend if not moving', (done) => { + const camera = createCamera(); + const eventData = { data: 'ok' }; + + camera.on('moveend', (d) => { + expect(d.data).toBe('ok'); + camera.stop(); + done(); // Fails with ".end() called twice" if we get here a second time. + }); + + const stub = jest.spyOn(browser, 'now'); + stub.mockImplementation(() => 0); + camera.panTo([100, 0], { duration: 1 }, eventData); + + setTimeout(() => { + stub.mockImplementation(() => 1); + camera.simulateFrame(); + }, 0); + }); +}); + +describe('#cameraForBounds', () => { + test('no options passed', () => { + const camera = createCamera(); + const bb = [ + [-133, 16], + [-68, 50], + ]; + const transform = camera.cameraForBounds(bb); + + expect(fixedLngLat(transform.center, 4)).toEqual({ lng: -100.5, lat: 34.7171 }); + expect(fixedNum(transform.zoom, 3)).toBe(2.469); + }); + + test('bearing positive number', () => { + const camera = createCamera(); + const bb = [ + [-133, 16], + [-68, 50], + ]; + const transform = camera.cameraForBounds(bb, { bearing: 175 }); + + expect(fixedLngLat(transform.center, 4)).toEqual({ lng: -100.5, lat: 34.7171 }); + expect(fixedNum(transform.zoom, 3)).toBe(2.396); + expect(transform.bearing).toBe(175); + }); + + test('bearing negative number', () => { + const camera = createCamera(); + const bb = [ + [-133, 16], + [-68, 50], + ]; + const transform = camera.cameraForBounds(bb, { bearing: -30 }); + + expect(fixedLngLat(transform.center, 4)).toEqual({ lng: -100.5, lat: 34.7171 }); + expect(fixedNum(transform.zoom, 3)).toBe(2.222); + expect(transform.bearing).toBe(-30); + }); + + test('padding number', () => { + const camera = createCamera(); + const bb = [ + [-133, 16], + [-68, 50], + ]; + const transform = camera.cameraForBounds(bb, { padding: 15 }); + + expect(fixedLngLat(transform.center, 4)).toEqual({ lng: -100.5, lat: 34.7171 }); + expect(fixedNum(transform.zoom, 3)).toBe(2.382); + }); + + test('padding object', () => { + const camera = createCamera(); + const bb = [ + [-133, 16], + [-68, 50], + ]; + const transform = camera.cameraForBounds(bb, { + padding: { top: 15, right: 15, bottom: 15, left: 15 }, + duration: 0, + }); + + expect(fixedLngLat(transform.center, 4)).toEqual({ lng: -100.5, lat: 34.7171 }); + }); + + test('asymmetrical padding', () => { + const camera = createCamera(); + const bb = [ + [-133, 16], + [-68, 50], + ]; + const transform = camera.cameraForBounds(bb, { + padding: { top: 10, right: 75, bottom: 50, left: 25 }, + duration: 0, + }); + + expect(fixedLngLat(transform.center, 4)).toEqual({ lng: -96.5558, lat: 32.0833 }); + }); + + test('bearing and asymmetrical padding', () => { + const camera = createCamera(); + const bb = [ + [-133, 16], + [-68, 50], + ]; + const transform = camera.cameraForBounds(bb, { + bearing: 90, + padding: { top: 10, right: 75, bottom: 50, left: 25 }, + duration: 0, + }); + + expect(fixedLngLat(transform.center, 4)).toEqual({ lng: -103.3761, lat: 31.7099 }); + }); + + test('offset', () => { + const camera = createCamera(); + const bb = [ + [-133, 16], + [-68, 50], + ]; + const transform = camera.cameraForBounds(bb, { offset: [0, 100] }); + + expect(fixedLngLat(transform.center, 4)).toEqual({ lng: -100.5, lat: 44.4717 }); + }); + + test('offset and padding', () => { + const camera = createCamera(); + const bb = [ + [-133, 16], + [-68, 50], + ]; + const transform = camera.cameraForBounds(bb, { + padding: { top: 10, right: 75, bottom: 50, left: 25 }, + offset: [0, 100], + }); + + expect(fixedLngLat(transform.center, 4)).toEqual({ lng: -96.5558, lat: 44.4189 }); + }); + + test('bearing, asymmetrical padding, and offset', () => { + const camera = createCamera(); + const bb = [ + [-133, 16], + [-68, 50], + ]; + const transform = camera.cameraForBounds(bb, { + bearing: 90, + padding: { top: 10, right: 75, bottom: 50, left: 25 }, + offset: [0, 100], + duration: 0, + }); + + expect(fixedLngLat(transform.center, 4)).toEqual({ lng: -103.3761, lat: 43.0929 }); + }); + + test('asymmetrical transform using LngLatBounds instance', () => { + const transform = new Transform(2, 10, 0, 60, false); + transform.resize(2048, 512); + + const camera = attachSimulateFrame(new CameraMock(transform, {} as any)); + camera._update = () => {}; + + const bb = new LngLatBounds(); + bb.extend([-66.9326, 49.5904]); + bb.extend([-125.0011, 24.9493]); + + const rotatedTransform = camera.cameraForBounds(bb, { bearing: 45 }); + + expect(fixedLngLat(rotatedTransform.center, 4)).toEqual({ lng: -95.9669, lat: 38.3048 }); + expect(fixedNum(rotatedTransform.zoom, 3)).toBe(2.507); + expect(rotatedTransform.bearing).toBe(45); + }); +}); + +describe('#fitBounds', () => { + test('no padding passed', () => { + const camera = createCamera(); + const bb = [ + [-133, 16], + [-68, 50], + ]; + camera.fitBounds(bb, { duration: 0 }); + + expect(fixedLngLat(camera.getCenter(), 4)).toEqual({ lng: -100.5, lat: 34.7171 }); + expect(fixedNum(camera.getZoom(), 3)).toBe(2.469); + }); + + test('padding number', () => { + const camera = createCamera(); + const bb = [ + [-133, 16], + [-68, 50], + ]; + camera.fitBounds(bb, { padding: 15, duration: 0 }); + + expect(fixedLngLat(camera.getCenter(), 4)).toEqual({ lng: -100.5, lat: 34.7171 }); + expect(fixedNum(camera.getZoom(), 3)).toBe(2.382); + }); + + test('padding object', () => { + const camera = createCamera(); + const bb = [ + [-133, 16], + [-68, 50], + ]; + camera.fitBounds(bb, { padding: { top: 10, right: 75, bottom: 50, left: 25 }, duration: 0 }); + + expect(fixedLngLat(camera.getCenter(), 4)).toEqual({ lng: -96.5558, lat: 32.0833 }); + }); + + test('padding does not get propagated to transform.padding', () => { + const camera = createCamera(); + const bb = [ + [-133, 16], + [-68, 50], + ]; + camera.fitBounds(bb, { padding: { top: 10, right: 75, bottom: 50, left: 25 }, duration: 0 }); + const padding = camera.transform.padding; + + expect(padding).toEqual({ + left: 0, + right: 0, + top: 0, + bottom: 0, + }); + }); +}); + +describe('#fitScreenCoordinates', () => { + test('bearing 225', () => { + const camera = createCamera(); + const p0 = [128, 128]; + const p1 = [256, 256]; + const bearing = 225; + camera.fitScreenCoordinates(p0, p1, bearing, { duration: 0 }); + + expect(fixedLngLat(camera.getCenter(), 4)).toEqual({ lng: -45, lat: 40.9799 }); + expect(fixedNum(camera.getZoom(), 3)).toBe(1.5); + expect(camera.getBearing()).toBe(-135); + }); + + test('bearing 0', () => { + const camera = createCamera(); + const p0 = [128, 128]; + const p1 = [256, 256]; + const bearing = 0; + camera.fitScreenCoordinates(p0, p1, bearing, { duration: 0 }); + + expect(fixedLngLat(camera.getCenter(), 4)).toEqual({ lng: -45, lat: 40.9799 }); + expect(fixedNum(camera.getZoom(), 3)).toBe(2); + expect(camera.getBearing()).toBeCloseTo(0); + }); + + test('inverted points', () => { + const camera = createCamera(); + const p1 = [128, 128]; + const p0 = [256, 256]; + const bearing = 0; + camera.fitScreenCoordinates(p0, p1, bearing, { duration: 0 }); + + expect(fixedLngLat(camera.getCenter(), 4)).toEqual({ lng: -45, lat: 40.9799 }); + expect(fixedNum(camera.getZoom(), 3)).toBe(2); + expect(camera.getBearing()).toBeCloseTo(0); + }); +}); + +describe('#transformCameraUpdate', () => { + test('invoke transformCameraUpdate callback during jumpTo', (done) => { + const camera = createCamera(); + + let callbackCount = 0; + let eventCount = 0; + + camera.transformCameraUpdate = () => { + callbackCount++; + return {}; + }; + + camera + .on('move', () => { + eventCount++; + expect(eventCount).toBe(callbackCount); + }) + .on('moveend', () => { + done(); + }); + + camera.jumpTo({ center: [100, 0] }); + }); + + test('invoke transformCameraUpdate callback during easeTo', (done) => { + expect.assertions(2); + const camera = createCamera(); + const stub = jest.spyOn(browser, 'now'); + stub.mockImplementation(() => 0); + + let callbackCount = 0; + let eventCount = 0; + + camera.transformCameraUpdate = () => { + callbackCount++; + return {}; + }; + + camera + .on('move', () => { + eventCount++; + expect(eventCount).toBe(callbackCount); + }) + .on('moveend', () => { + done(); + }); + + camera.easeTo({ center: [100, 0], duration: 10 }); + + setTimeout(() => { + stub.mockImplementation(() => 1); + camera.simulateFrame(); + + setTimeout(() => { + stub.mockImplementation(() => 10); + camera.simulateFrame(); + }, 0); + }, 0); + }); + + test('invoke transformCameraUpdate callback during flyTo', (done) => { + expect.assertions(2); + const camera = createCamera(); + const stub = jest.spyOn(browser, 'now'); + stub.mockImplementation(() => 0); + + let callbackCount = 0; + let eventCount = 0; + + camera.transformCameraUpdate = () => { + callbackCount++; + return {}; + }; + + camera + .on('move', () => { + eventCount++; + expect(eventCount).toBe(callbackCount); + }) + .on('moveend', () => { + done(); + }); + + camera.flyTo({ center: [100, 0], duration: 10 }); + + setTimeout(() => { + stub.mockImplementation(() => 1); + camera.simulateFrame(); + + setTimeout(() => { + stub.mockImplementation(() => 10); + camera.simulateFrame(); + }, 0); + }, 0); + }); + + test('transformCameraUpdate overrides proposed camera settings', () => { + const camera = createCamera(); + + camera.transformCameraUpdate = ({ center, zoom }) => { + return { + center: LngLat.convert([center.lng, center.lat + 10]), + zoom: Math.round(zoom), + }; + }; + + camera.flyTo({ center: [100, 0], zoom: 3.2, animate: false }); + expect(fixedLngLat(camera.getCenter())).toEqual({ lng: 100, lat: 10 }); + expect(fixedNum(camera.getZoom())).toBe(3); + }); +}); diff --git a/packages/map/__tests__/geo/edge_insets.spec.ts b/packages/map/__tests__/geo/edge_insets.spec.ts new file mode 100644 index 00000000000..a46dc483c08 --- /dev/null +++ b/packages/map/__tests__/geo/edge_insets.spec.ts @@ -0,0 +1,81 @@ +import { EdgeInsets } from '../../src/map/geo/edge_insets'; + +describe('EdgeInsets', () => { + describe('#constructor', () => { + test('creates an object with default values', () => { + expect(new EdgeInsets() instanceof EdgeInsets).toBeTruthy(); + }); + + test('invalid initialization', () => { + expect(() => { + new EdgeInsets(NaN, 10); + }).toThrow('Invalid value for edge-insets, top, bottom, left and right must all be numbers'); + + expect(() => { + new EdgeInsets(-10, 10, 20, 10); + }).toThrow('Invalid value for edge-insets, top, bottom, left and right must all be numbers'); + }); + + test('valid initialization', () => { + const top = 10; + const bottom = 15; + const left = 26; + const right = 19; + + const inset = new EdgeInsets(top, bottom, left, right); + expect(inset.top).toBe(top); + expect(inset.bottom).toBe(bottom); + expect(inset.left).toBe(left); + expect(inset.right).toBe(right); + }); + }); + + describe('#getCenter', () => { + test('valid input', () => { + const inset = new EdgeInsets(10, 15, 50, 10); + const center = inset.getCenter(600, 400); + expect(center.x).toBe(320); + expect(center.y).toBe(197.5); + }); + + test('center clamping', () => { + const inset = new EdgeInsets(300, 200, 500, 200); + const center = inset.getCenter(600, 400); + + // Midpoint of the overlap when padding overlaps + expect(center.x).toBe(450); + expect(center.y).toBe(250); + }); + }); + + describe('#interpolate', () => { + test('it works', () => { + const inset1 = new EdgeInsets(10, 15, 50, 10); + const inset2 = new EdgeInsets(20, 30, 100, 10); + const inset3 = inset1.interpolate(inset1, inset2, 0.5); + + // inset1 is mutated in-place + expect(inset3).toBe(inset1); + + expect(inset3.top).toBe(15); + expect(inset3.bottom).toBe(22.5); + expect(inset3.left).toBe(75); + expect(inset3.right).toBe(10); + }); + }); + + test('#equals', () => { + const inset1 = new EdgeInsets(10, 15, 50, 10); + const inset2 = new EdgeInsets(10, 15, 50, 10); + const inset3 = new EdgeInsets(10, 15, 50, 11); + expect(inset1.equals(inset2)).toBeTruthy(); + expect(inset2.equals(inset3)).toBeFalsy(); + }); + + test('#clone', () => { + const inset1 = new EdgeInsets(10, 15, 50, 10); + const inset2 = inset1.clone(); + expect(inset2 === inset1).toBeFalsy(); + expect(inset1.equals(inset2)).toBeTruthy(); + }); +}); diff --git a/packages/map/__tests__/geo/lng_lat.spec.ts b/packages/map/__tests__/geo/lng_lat.spec.ts new file mode 100644 index 00000000000..28624475649 --- /dev/null +++ b/packages/map/__tests__/geo/lng_lat.spec.ts @@ -0,0 +1,65 @@ +import { LngLat } from '../../src/map/geo/lng_lat'; + +describe('LngLat', () => { + test('#constructor', () => { + expect(new LngLat(0, 0) instanceof LngLat).toBeTruthy(); + + expect(() => { + /*eslint no-new: 0*/ + new LngLat(0, -91); + }).toThrow('Invalid LngLat latitude value: must be between -90 and 90'); + + expect(() => { + /*eslint no-new: 0*/ + new LngLat(0, 91); + }).toThrow('Invalid LngLat latitude value: must be between -90 and 90'); + }); + + test('#convert', () => { + expect(LngLat.convert([0, 10]) instanceof LngLat).toBeTruthy(); + expect(LngLat.convert({ lng: 0, lat: 10 }) instanceof LngLat).toBeTruthy(); + expect(LngLat.convert({ lng: 0, lat: 0 }) instanceof LngLat).toBeTruthy(); + expect(LngLat.convert({ lon: 0, lat: 10 }) instanceof LngLat).toBeTruthy(); + expect(LngLat.convert({ lon: 0, lat: 0 }) instanceof LngLat).toBeTruthy(); + expect(LngLat.convert(new LngLat(0, 0)) instanceof LngLat).toBeTruthy(); + }); + + test('#wrap', () => { + expect(new LngLat(0, 0).wrap()).toEqual({ lng: 0, lat: 0 }); + expect(new LngLat(10, 20).wrap()).toEqual({ lng: 10, lat: 20 }); + expect(new LngLat(360, 0).wrap()).toEqual({ lng: 0, lat: 0 }); + expect(new LngLat(190, 0).wrap()).toEqual({ lng: -170, lat: 0 }); + }); + + test('#toArray', () => { + expect(new LngLat(10, 20).toArray()).toEqual([10, 20]); + }); + + test('#toString', () => { + expect(new LngLat(10, 20).toString()).toBe('LngLat(10, 20)'); + }); + + test('#distanceTo', () => { + const newYork = new LngLat(-74.006, 40.7128); + const losAngeles = new LngLat(-118.2437, 34.0522); + const d = newYork.distanceTo(losAngeles); // 3935751.690893987, "true distance" is 3966km + expect(d > 3935750).toBeTruthy(); + expect(d < 3935752).toBeTruthy(); + }); + + test('#distanceTo to pole', () => { + const newYork = new LngLat(-74.006, 40.7128); + const northPole = new LngLat(-135, 90); + const d = newYork.distanceTo(northPole); // 5480494.158486183 , "true distance" is 5499km + expect(d > 5480493).toBeTruthy(); + expect(d < 5480495).toBeTruthy(); + }); + + test('#distanceTo to Null Island', () => { + const newYork = new LngLat(-74.006, 40.7128); + const nullIsland = new LngLat(0, 0); + const d = newYork.distanceTo(nullIsland); // 8667080.125666846 , "true distance" is 8661km + expect(d > 8667079).toBeTruthy(); + expect(d < 8667081).toBeTruthy(); + }); +}); diff --git a/packages/map/__tests__/geo/lng_lat_bounds.spec.ts b/packages/map/__tests__/geo/lng_lat_bounds.spec.ts new file mode 100644 index 00000000000..1ee5c63efdc --- /dev/null +++ b/packages/map/__tests__/geo/lng_lat_bounds.spec.ts @@ -0,0 +1,249 @@ +import { LngLat } from '../../src/map/geo/lng_lat'; +import { LngLatBounds } from '../../src/map/geo/lng_lat_bounds'; + +describe('LngLatBounds', () => { + test('#constructor', () => { + const sw = new LngLat(0, 0); + const ne = new LngLat(-10, 10); + const bounds = new LngLatBounds(sw, ne); + expect(bounds.getSouth()).toBe(0); + expect(bounds.getWest()).toBe(0); + expect(bounds.getNorth()).toBe(10); + expect(bounds.getEast()).toBe(-10); + }); + + test('#constructor across dateline', () => { + const sw = new LngLat(170, 0); + const ne = new LngLat(-170, 10); + const bounds = new LngLatBounds(sw, ne); + expect(bounds.getSouth()).toBe(0); + expect(bounds.getWest()).toBe(170); + expect(bounds.getNorth()).toBe(10); + expect(bounds.getEast()).toBe(-170); + }); + + test('#constructor across pole', () => { + const sw = new LngLat(0, 85); + const ne = new LngLat(-10, -85); + const bounds = new LngLatBounds(sw, ne); + expect(bounds.getSouth()).toBe(85); + expect(bounds.getWest()).toBe(0); + expect(bounds.getNorth()).toBe(-85); + expect(bounds.getEast()).toBe(-10); + }); + + test('#constructor no args', () => { + const bounds = new LngLatBounds(); + const t1 = () => { + bounds.getCenter(); + }; + expect(t1).toThrow(); + }); + + test('#extend with coordinate', () => { + const bounds = new LngLatBounds([0, 0], [10, 10]); + bounds.extend([-10, -10]); + + expect(bounds.getSouth()).toBe(-10); + expect(bounds.getWest()).toBe(-10); + expect(bounds.getNorth()).toBe(10); + expect(bounds.getEast()).toBe(10); + + bounds.extend(new LngLat(-15, -15)); + + expect(bounds.getSouth()).toBe(-15); + expect(bounds.getWest()).toBe(-15); + expect(bounds.getNorth()).toBe(10); + expect(bounds.getEast()).toBe(10); + + bounds.extend([-80, -80, 80, 80]); + + expect(bounds.getSouth()).toBe(-80); + expect(bounds.getWest()).toBe(-80); + expect(bounds.getNorth()).toBe(80); + expect(bounds.getEast()).toBe(80); + + bounds.extend({ lng: -90, lat: -90 }); + + expect(bounds.getSouth()).toBe(-90); + expect(bounds.getWest()).toBe(-90); + expect(bounds.getNorth()).toBe(80); + expect(bounds.getEast()).toBe(80); + + bounds.extend({ lon: 90, lat: 90 }); + + expect(bounds.getSouth()).toBe(-90); + expect(bounds.getWest()).toBe(-90); + expect(bounds.getNorth()).toBe(90); + expect(bounds.getEast()).toBe(90); + }); + + test('#extend with bounds', () => { + const bounds1 = new LngLatBounds([0, 0], [10, 10]); + const bounds2 = new LngLatBounds([-10, -10], [10, 10]); + + bounds1.extend(bounds2); + + expect(bounds1.getSouth()).toBe(-10); + expect(bounds1.getWest()).toBe(-10); + expect(bounds1.getNorth()).toBe(10); + expect(bounds1.getEast()).toBe(10); + + const bounds4 = new LngLatBounds([-20, -20, 20, 20]); + bounds1.extend(bounds4); + + expect(bounds1.getSouth()).toBe(-20); + expect(bounds1.getWest()).toBe(-20); + expect(bounds1.getNorth()).toBe(20); + expect(bounds1.getEast()).toBe(20); + + const bounds5 = new LngLatBounds(); + bounds1.extend(bounds5); + + expect(bounds1.getSouth()).toBe(-20); + expect(bounds1.getWest()).toBe(-20); + expect(bounds1.getNorth()).toBe(20); + expect(bounds1.getEast()).toBe(20); + }); + + test('#extend with null', () => { + const bounds = new LngLatBounds([0, 0], [10, 10]); + + bounds.extend(null); + + expect(bounds.getSouth()).toBe(0); + expect(bounds.getWest()).toBe(0); + expect(bounds.getNorth()).toBe(10); + expect(bounds.getEast()).toBe(10); + }); + + test('#extend undefined bounding box', () => { + const bounds1 = new LngLatBounds(undefined, undefined); + const bounds2 = new LngLatBounds([-10, -10], [10, 10]); + + bounds1.extend(bounds2); + + expect(bounds1.getSouth()).toBe(-10); + expect(bounds1.getWest()).toBe(-10); + expect(bounds1.getNorth()).toBe(10); + expect(bounds1.getEast()).toBe(10); + }); + + test('#extend same LngLat instance', () => { + const point = new LngLat(0, 0); + const bounds = new LngLatBounds(point, point); + + bounds.extend(new LngLat(15, 15)); + + expect(bounds.getSouth()).toBe(0); + expect(bounds.getWest()).toBe(0); + expect(bounds.getNorth()).toBe(15); + expect(bounds.getEast()).toBe(15); + }); + + test('accessors', () => { + const sw = new LngLat(0, 0); + const ne = new LngLat(-10, -20); + const bounds = new LngLatBounds(sw, ne); + expect(bounds.getCenter()).toEqual(new LngLat(-5, -10)); + expect(bounds.getSouth()).toBe(0); + expect(bounds.getWest()).toBe(0); + expect(bounds.getNorth()).toBe(-20); + expect(bounds.getEast()).toBe(-10); + expect(bounds.getSouthWest()).toEqual(new LngLat(0, 0)); + expect(bounds.getSouthEast()).toEqual(new LngLat(-10, 0)); + expect(bounds.getNorthEast()).toEqual(new LngLat(-10, -20)); + expect(bounds.getNorthWest()).toEqual(new LngLat(0, -20)); + }); + + test('#convert', () => { + const sw = new LngLat(0, 0); + const ne = new LngLat(-10, 10); + const bounds = new LngLatBounds(sw, ne); + expect(LngLatBounds.convert(bounds)).toEqual(bounds); + expect(LngLatBounds.convert([sw, ne])).toEqual(bounds); + expect( + LngLatBounds.convert([ + bounds.getWest(), + bounds.getSouth(), + bounds.getEast(), + bounds.getNorth(), + ]), + ).toEqual(bounds); + }); + + test('#toArray', () => { + const llb = new LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]); + expect(llb.toArray()).toEqual([ + [-73.9876, 40.7661], + [-73.9397, 40.8002], + ]); + }); + + test('#toString', () => { + const llb = new LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]); + expect(llb.toString()).toBe( + 'LngLatBounds(LngLat(-73.9876, 40.7661), LngLat(-73.9397, 40.8002))', + ); + }); + + test('#isEmpty', () => { + const nullBounds = new LngLatBounds(); + expect(nullBounds.isEmpty()).toBe(true); + + const sw = new LngLat(0, 0); + const ne = new LngLat(-10, 10); + const bounds = new LngLatBounds(sw, ne); + expect(bounds.isEmpty()).toBe(false); + }); + + test('#fromLngLat', () => { + const center0 = new LngLat(0, 0); + const center1 = new LngLat(-73.9749, 40.7736); + + const center0Radius10 = LngLatBounds.fromLngLat(center0, 10); + const center1Radius10 = LngLatBounds.fromLngLat(center1, 10); + const center1Radius0 = LngLatBounds.fromLngLat(center1); + + expect(center0Radius10.toArray()).toEqual([ + [-0.00008983152770714982, -0.00008983152770714982], + [0.00008983152770714982, 0.00008983152770714982], + ]); + expect(center1Radius10.toArray()).toEqual([ + [-73.97501862141328, 40.77351016847229], + [-73.97478137858673, 40.77368983152771], + ]); + expect(center1Radius0.toArray()).toEqual([ + [-73.9749, 40.7736], + [-73.9749, 40.7736], + ]); + }); + + describe('contains', () => { + describe('point', () => { + test('point is in bounds', () => { + const llb = new LngLatBounds([-1, -1], [1, 1]); + const ll = { lng: 0, lat: 0 }; + expect(llb.contains(ll)).toBeTruthy(); + }); + + test('point is not in bounds', () => { + const llb = new LngLatBounds([-1, -1], [1, 1]); + const ll = { lng: 3, lat: 3 }; + expect(llb.contains(ll)).toBeFalsy(); + }); + + test('point is in bounds that spans dateline', () => { + const llb = new LngLatBounds([190, -10], [170, 10]); + const ll = { lng: 180, lat: 0 }; + expect(llb.contains(ll)).toBeTruthy(); + }); + + test('point is not in bounds that spans dateline', () => { + const llb = new LngLatBounds([190, -10], [170, 10]); + const ll = { lng: 0, lat: 0 }; + expect(llb.contains(ll)).toBeFalsy(); + }); + }); + }); +}); diff --git a/packages/map/__tests__/geo/mercator_coordinate.spec.ts b/packages/map/__tests__/geo/mercator_coordinate.spec.ts new file mode 100644 index 00000000000..e0647639438 --- /dev/null +++ b/packages/map/__tests__/geo/mercator_coordinate.spec.ts @@ -0,0 +1,36 @@ +import { LngLat } from '../../src/map/geo/lng_lat'; +import { MercatorCoordinate, mercatorScale } from '../../src/map/geo/mercator_coordinate'; + +describe('LngLat', () => { + test('#constructor', () => { + expect(new MercatorCoordinate(0, 0) instanceof MercatorCoordinate).toBeTruthy(); + expect(new MercatorCoordinate(0, 0, 0) instanceof MercatorCoordinate).toBeTruthy(); + }); + + test('#fromLngLat', () => { + const nullIsland = new LngLat(0, 0); + expect(MercatorCoordinate.fromLngLat(nullIsland)).toEqual({ x: 0.5, y: 0.5, z: 0 }); + }); + + test('#toLngLat', () => { + const dc = new LngLat(-77, 39); + expect(MercatorCoordinate.fromLngLat(dc, 500).toLngLat()).toEqual({ lng: -77, lat: 39 }); + }); + + test('#toAltitude', () => { + const dc = new LngLat(-77, 39); + expect(MercatorCoordinate.fromLngLat(dc, 500).toAltitude()).toBe(500); + }); + + test('#mercatorScale', () => { + expect(mercatorScale(0)).toBe(1); + expect(mercatorScale(45)).toBe(1.414213562373095); + }); + + test('#meterInMercatorCoordinateUnits', () => { + const nullIsland = new LngLat(0, 0); + expect(MercatorCoordinate.fromLngLat(nullIsland).meterInMercatorCoordinateUnits()).toBe( + 2.4981121214570498e-8, + ); + }); +}); diff --git a/packages/map/__tests__/geo/transform.spec.ts b/packages/map/__tests__/geo/transform.spec.ts new file mode 100644 index 00000000000..10fe9fac1c6 --- /dev/null +++ b/packages/map/__tests__/geo/transform.spec.ts @@ -0,0 +1,294 @@ +import Point from '@mapbox/point-geometry'; +import { LngLat } from '../../src/map/geo/lng_lat'; +import { MAX_VALID_LATITUDE, Transform } from '../../src/map/geo/transform'; +import { fixedCoord, fixedLngLat } from '../libs/fixed'; + +describe('transform', () => { + test('creates a transform', () => { + const transform = new Transform(0, 22, 0, 60, true); + transform.resize(500, 500); + expect(transform.unmodified).toBe(true); + expect(transform.tileSize).toBe(512); + expect(transform.worldSize).toBe(512); + expect(transform.width).toBe(500); + expect(transform.minZoom).toBe(0); + expect(transform.minPitch).toBe(0); + // Support signed zero + expect(transform.bearing === 0 ? 0 : transform.bearing).toBe(0); + expect((transform.bearing = 1)).toBe(1); + expect(transform.bearing).toBe(1); + expect((transform.bearing = 0)).toBe(0); + expect(transform.unmodified).toBe(false); + expect((transform.minZoom = 10)).toBe(10); + expect((transform.maxZoom = 10)).toBe(10); + expect(transform.minZoom).toBe(10); + expect(transform.center).toEqual({ lng: 0, lat: 0 }); + expect(transform.maxZoom).toBe(10); + expect((transform.minPitch = 10)).toBe(10); + expect((transform.maxPitch = 10)).toBe(10); + expect(transform.size.equals(new Point(500, 500))).toBe(true); + expect(transform.centerPoint.equals(new Point(250, 250))).toBe(true); + expect(transform.scaleZoom(0)).toBe(-Infinity); + expect(transform.scaleZoom(10)).toBe(3.3219280948873626); + expect(transform.point).toEqual(new Point(262144, 262144)); + expect(transform.height).toBe(500); + expect(fixedLngLat(transform.pointLocation(new Point(250, 250)))).toEqual({ lng: 0, lat: 0 }); + expect(fixedCoord(transform.pointCoordinate(new Point(250, 250)))).toEqual({ + x: 0.5, + y: 0.5, + z: 0, + }); + expect(transform.locationPoint(new LngLat(0, 0))).toEqual({ x: 250, y: 250 }); + expect(transform.locationCoordinate(new LngLat(0, 0))).toEqual({ x: 0.5, y: 0.5, z: 0 }); + }); + + test('does not throw on bad center', () => { + expect(() => { + const transform = new Transform(0, 22, 0, 60, true); + transform.resize(500, 500); + transform.center = new LngLat(50, -90); + }).not.toThrow(); + }); + + test('setLocationAt', () => { + const transform = new Transform(0, 22, 0, 60, true); + transform.resize(500, 500); + transform.zoom = 4; + expect(transform.center).toEqual({ lng: 0, lat: 0 }); + transform.setLocationAtPoint(new LngLat(13, 10), new Point(15, 45)); + expect(fixedLngLat(transform.pointLocation(new Point(15, 45)))).toEqual({ lng: 13, lat: 10 }); + }); + + test('setLocationAt tilted', () => { + const transform = new Transform(0, 22, 0, 60, true); + transform.resize(500, 500); + transform.zoom = 4; + transform.pitch = 50; + expect(transform.center).toEqual({ lng: 0, lat: 0 }); + transform.setLocationAtPoint(new LngLat(13, 10), new Point(15, 45)); + expect(fixedLngLat(transform.pointLocation(new Point(15, 45)))).toEqual({ lng: 13, lat: 10 }); + }); + + test('has a default zoom', () => { + const transform = new Transform(0, 22, 0, 60, true); + transform.resize(500, 500); + expect(transform.tileZoom).toBe(0); + expect(transform.tileZoom).toBe(transform.zoom); + }); + + test('set zoom inits tileZoom with zoom value', () => { + const transform = new Transform(0, 22, 0, 60); + transform.zoom = 5; + expect(transform.tileZoom).toBe(5); + }); + + test('set zoom clamps tileZoom to non negative value ', () => { + const transform = new Transform(-2, 22, 0, 60); + transform.zoom = -2; + expect(transform.tileZoom).toBe(0); + }); + + test('set fov', () => { + const transform = new Transform(0, 22, 0, 60, true); + transform.fov = 10; + expect(transform.fov).toBe(10); + transform.fov = 10; + expect(transform.fov).toBe(10); + }); + + test('lngRange & latRange constrain zoom and center', () => { + const transform = new Transform(0, 22, 0, 60, true); + transform.center = new LngLat(0, 0); + transform.zoom = 10; + transform.resize(500, 500); + + transform.lngRange = [-5, 5]; + transform.latRange = [-5, 5]; + + transform.zoom = 0; + expect(transform.zoom).toBe(5.1357092861044045); + + transform.center = new LngLat(-50, -30); + expect(transform.center).toEqual(new LngLat(0, -0.0063583052861417855)); + + transform.zoom = 10; + transform.center = new LngLat(-50, -30); + expect(transform.center).toEqual(new LngLat(-4.828338623046875, -4.828969771321582)); + }); + + test('lngRange can constrain zoom and center across meridian', () => { + const transform = new Transform(0, 22, 0, 60, true); + transform.center = new LngLat(180, 0); + transform.zoom = 10; + transform.resize(500, 500); + + // equivalent ranges + const lngRanges: [number, number][] = [ + [175, -175], + [175, 185], + [-185, -175], + [-185, 185], + ]; + + for (const lngRange of lngRanges) { + transform.lngRange = lngRange; + transform.latRange = [-5, 5]; + + transform.zoom = 0; + expect(transform.zoom).toBe(5.1357092861044045); + + transform.center = new LngLat(-50, -30); + expect(transform.center).toEqual(new LngLat(180, -0.0063583052861417855)); + + transform.zoom = 10; + transform.center = new LngLat(-50, -30); + expect(transform.center).toEqual(new LngLat(-175.171661376953125, -4.828969771321582)); + + transform.center = new LngLat(230, 0); + expect(transform.center).toEqual(new LngLat(-175.171661376953125, 0)); + + transform.center = new LngLat(130, 0); + expect(transform.center).toEqual(new LngLat(175.171661376953125, 0)); + } + }); + + test('coveringZoomLevel', () => { + const options = { + minzoom: 1, + maxzoom: 10, + tileSize: 512, + roundZoom: false, + }; + + const transform = new Transform(0, 22, 0, 60, true); + + transform.zoom = 0; + expect(transform.coveringZoomLevel(options)).toBe(0); + + transform.zoom = 0.1; + expect(transform.coveringZoomLevel(options)).toBe(0); + + transform.zoom = 1; + expect(transform.coveringZoomLevel(options)).toBe(1); + + transform.zoom = 2.4; + expect(transform.coveringZoomLevel(options)).toBe(2); + + transform.zoom = 10; + expect(transform.coveringZoomLevel(options)).toBe(10); + + transform.zoom = 11; + expect(transform.coveringZoomLevel(options)).toBe(11); + + transform.zoom = 11.5; + expect(transform.coveringZoomLevel(options)).toBe(11); + + options.tileSize = 256; + + transform.zoom = 0; + expect(transform.coveringZoomLevel(options)).toBe(1); + + transform.zoom = 0.1; + expect(transform.coveringZoomLevel(options)).toBe(1); + + transform.zoom = 1; + expect(transform.coveringZoomLevel(options)).toBe(2); + + transform.zoom = 2.4; + expect(transform.coveringZoomLevel(options)).toBe(3); + + transform.zoom = 10; + expect(transform.coveringZoomLevel(options)).toBe(11); + + transform.zoom = 11; + expect(transform.coveringZoomLevel(options)).toBe(12); + + transform.zoom = 11.5; + expect(transform.coveringZoomLevel(options)).toBe(12); + + options.roundZoom = true; + + expect(transform.coveringZoomLevel(options)).toBe(13); + }); + + test('clamps latitude', () => { + const transform = new Transform(0, 22, 0, 60, true); + + expect(transform.project(new LngLat(0, -90))).toEqual( + transform.project(new LngLat(0, -MAX_VALID_LATITUDE)), + ); + expect(transform.project(new LngLat(0, 90))).toEqual( + transform.project(new LngLat(0, MAX_VALID_LATITUDE)), + ); + }); + + test('clamps pitch', () => { + const transform = new Transform(0, 22, 0, 60, true); + + transform.pitch = 45; + expect(transform.pitch).toBe(45); + + transform.pitch = -10; + expect(transform.pitch).toBe(0); + + transform.pitch = 90; + expect(transform.pitch).toBe(60); + }); + + test('maintains high float precision when calculating matrices', () => { + const transform = new Transform(0, 22, 0, 60, true); + transform.resize(200.25, 200.25); + transform.zoom = 20.25; + transform.pitch = 67.25; + transform.center = new LngLat(0.0, 0.0); + transform._calcMatrices(); + + expect(transform.customLayerMatrix()[0].toString().length).toBeGreaterThan(10); + expect(transform.glCoordMatrix[0].toString().length).toBeGreaterThan(10); + expect(transform.maxPitchScaleFactor()).toBeCloseTo(2.366025418080343, 5); + }); + + test('pointCoordinate with terrain when returning null should fall back to 2D', () => { + const transform = new Transform(0, 22, 0, 60, true); + transform.resize(500, 500); + const coordinate = transform.pointCoordinate(new Point(0, 0)); + + expect(coordinate).toBeDefined(); + }); + + test('horizon', () => { + const transform = new Transform(0, 22, 0, 85, true); + transform.resize(500, 500); + transform.pitch = 75; + const horizon = transform.getHorizon(); + + expect(horizon).toBeCloseTo(170.8176101748407, 10); + }); + + test('getBounds with horizon', () => { + const transform = new Transform(0, 22, 0, 85, true); + transform.resize(500, 500); + + transform.pitch = 60; + expect(transform.getBounds().getNorthWest().toArray()).toStrictEqual( + transform.pointLocation(new Point(0, 0)).toArray(), + ); + + transform.pitch = 75; + const top = Math.max(0, transform.height / 2 - transform.getHorizon()); + expect(top).toBeCloseTo(79.1823898251593, 10); + expect(transform.getBounds().getNorthWest().toArray()).toStrictEqual( + transform.pointLocation(new Point(0, top)).toArray(), + ); + }); + + test('lngLatToCameraDepth', () => { + const transform = new Transform(0, 22, 0, 85, true); + transform.resize(500, 500); + transform.center = new LngLat(10.0, 50.0); + + expect(transform.lngLatToCameraDepth(new LngLat(10, 50), 4)).toBeCloseTo(0.9997324396231673); + transform.pitch = 60; + expect(transform.lngLatToCameraDepth(new LngLat(10, 50), 4)).toBeCloseTo(0.9865782165762236); + }); +}); diff --git a/packages/map/__tests__/handler/box_zoom.spec.ts b/packages/map/__tests__/handler/box_zoom.spec.ts new file mode 100644 index 00000000000..35a9104f3ed --- /dev/null +++ b/packages/map/__tests__/handler/box_zoom.spec.ts @@ -0,0 +1,163 @@ +import { Map } from '../../src/map/map'; +import { DOM } from '../../src/map/util/dom'; +import simulate from '../libs/simulate_interaction'; +import { beforeMapTest } from '../libs/util'; + +function createMap(clickTolerance) { + return new Map({ container: DOM.create('div', '', window.document.body), clickTolerance }); +} + +beforeEach(() => { + beforeMapTest(); +}); + +describe('BoxZoomHandler', () => { + test('fires boxzoomstart and boxzoomend events at appropriate times', () => { + const map = createMap(undefined); + + const boxzoomstart = jest.fn(); + const boxzoomend = jest.fn(); + + map.on('boxzoomstart', boxzoomstart); + map.on('boxzoomend', boxzoomend); + + simulate.mousedown(map.getCanvasContainer(), { shiftKey: true, clientX: 0, clientY: 0 }); + map._renderTaskQueue.run(); + expect(boxzoomstart).not.toHaveBeenCalled(); + expect(boxzoomend).not.toHaveBeenCalled(); + + simulate.mousemove(map.getCanvasContainer(), { shiftKey: true, clientX: 5, clientY: 5 }); + map._renderTaskQueue.run(); + expect(boxzoomstart).toHaveBeenCalledTimes(1); + expect(boxzoomend).not.toHaveBeenCalled(); + + simulate.mouseup(map.getCanvasContainer(), { shiftKey: true, clientX: 5, clientY: 5 }); + map._renderTaskQueue.run(); + expect(boxzoomstart).toHaveBeenCalledTimes(1); + expect(boxzoomend).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test('avoids conflicts with DragPanHandler when disabled and reenabled (#2237)', () => { + const map = createMap(undefined); + + map.boxZoom.disable(); + map.boxZoom.enable(); + + const boxzoomstart = jest.fn(); + const boxzoomend = jest.fn(); + + map.on('boxzoomstart', boxzoomstart); + map.on('boxzoomend', boxzoomend); + + const dragstart = jest.fn(); + const drag = jest.fn(); + const dragend = jest.fn(); + + map.on('dragstart', dragstart); + map.on('drag', drag); + map.on('dragend', dragend); + + simulate.mousedown(map.getCanvasContainer(), { shiftKey: true, clientX: 0, clientY: 0 }); + map._renderTaskQueue.run(); + expect(boxzoomstart).not.toHaveBeenCalled(); + expect(boxzoomend).not.toHaveBeenCalled(); + + simulate.mousemove(map.getCanvasContainer(), { shiftKey: true, clientX: 5, clientY: 5 }); + map._renderTaskQueue.run(); + expect(boxzoomstart).toHaveBeenCalledTimes(1); + expect(boxzoomend).not.toHaveBeenCalled(); + + simulate.mouseup(map.getCanvasContainer(), { shiftKey: true, clientX: 5, clientY: 5 }); + map._renderTaskQueue.run(); + expect(boxzoomstart).toHaveBeenCalledTimes(1); + expect(boxzoomend).toHaveBeenCalledTimes(1); + + expect(dragstart).not.toHaveBeenCalled(); + expect(drag).not.toHaveBeenCalled(); + expect(dragend).not.toHaveBeenCalled(); + + map.remove(); + }); + + test('does not begin a box zoom if preventDefault is called on the mousedown event', () => { + const map = createMap(undefined); + + map.on('mousedown', (e) => e.preventDefault()); + + const boxzoomstart = jest.fn(); + const boxzoomend = jest.fn(); + + map.on('boxzoomstart', boxzoomstart); + map.on('boxzoomend', boxzoomend); + + simulate.mousedown(map.getCanvasContainer(), { shiftKey: true, clientX: 0, clientY: 0 }); + map._renderTaskQueue.run(); + + simulate.mousemove(map.getCanvasContainer(), { shiftKey: true, clientX: 5, clientY: 5 }); + map._renderTaskQueue.run(); + + simulate.mouseup(map.getCanvasContainer(), { shiftKey: true, clientX: 5, clientY: 5 }); + map._renderTaskQueue.run(); + + expect(boxzoomstart).not.toHaveBeenCalled(); + expect(boxzoomend).not.toHaveBeenCalled(); + + map.remove(); + }); + + test('does not begin a box zoom on spurious mousemove events', () => { + const map = createMap(undefined); + + const boxzoomstart = jest.fn(); + const boxzoomend = jest.fn(); + + map.on('boxzoomstart', boxzoomstart); + map.on('boxzoomend', boxzoomend); + + simulate.mousedown(map.getCanvasContainer(), { shiftKey: true, clientX: 0, clientY: 0 }); + map._renderTaskQueue.run(); + expect(boxzoomstart).not.toHaveBeenCalled(); + expect(boxzoomend).not.toHaveBeenCalled(); + + simulate.mousemove(map.getCanvasContainer(), { shiftKey: true, clientX: 0, clientY: 0 }); + map._renderTaskQueue.run(); + expect(boxzoomstart).not.toHaveBeenCalled(); + expect(boxzoomend).not.toHaveBeenCalled(); + + simulate.mouseup(map.getCanvasContainer(), { shiftKey: true, clientX: 0, clientY: 0 }); + map._renderTaskQueue.run(); + expect(boxzoomstart).not.toHaveBeenCalled(); + expect(boxzoomend).not.toHaveBeenCalled(); + + map.remove(); + }); + + test('does not begin a box zoom until mouse move is larger than click tolerance', () => { + const map = createMap(4); + + const boxzoomstart = jest.fn(); + const boxzoomend = jest.fn(); + + map.on('boxzoomstart', boxzoomstart); + map.on('boxzoomend', boxzoomend); + + simulate.mousedown(map.getCanvasContainer(), { shiftKey: true, clientX: 0, clientY: 0 }); + map._renderTaskQueue.run(); + expect(boxzoomstart).not.toHaveBeenCalled(); + expect(boxzoomend).not.toHaveBeenCalled(); + + simulate.mousemove(map.getCanvasContainer(), { shiftKey: true, clientX: 3, clientY: 0 }); + map._renderTaskQueue.run(); + expect(boxzoomstart).not.toHaveBeenCalled(); + expect(boxzoomend).not.toHaveBeenCalled(); + + simulate.mousemove(map.getCanvasContainer(), { shiftKey: true, clientX: 0, clientY: 4 }); + map._renderTaskQueue.run(); + expect(boxzoomstart).toHaveBeenCalledTimes(1); + expect(boxzoomend).not.toHaveBeenCalled(); + + map.remove(); + }); +}); diff --git a/packages/map/__tests__/handler/dblclick_zoom.spec.ts b/packages/map/__tests__/handler/dblclick_zoom.spec.ts new file mode 100644 index 00000000000..2fc108b0ce9 --- /dev/null +++ b/packages/map/__tests__/handler/dblclick_zoom.spec.ts @@ -0,0 +1,161 @@ +import type { MapOptions } from '../../src/map/map'; +import { Map } from '../../src/map/map'; +import simulate from '../libs/simulate_interaction'; +import { beforeMapTest } from '../libs/util'; + +function createMap() { + return new Map({ container: window.document.createElement('div') } as any as MapOptions); +} + +function simulateDoubleTap(map, delay = 100) { + const canvas = map.getCanvasContainer(); + return new Promise((resolve) => { + simulate.touchstart(canvas, { touches: [{ target: canvas, clientX: 0, clientY: 0 }] }); + simulate.touchend(canvas); + setTimeout(() => { + simulate.touchstart(canvas, { touches: [{ target: canvas, clientX: 0, clientY: 0 }] }); + simulate.touchend(canvas); + map._renderTaskQueue.run(); + resolve(undefined); + }, delay); + }); +} + +beforeEach(() => { + beforeMapTest(); +}); + +describe('dbclick_zoom', () => { + test('DoubleClickZoomHandler zooms on dblclick event', () => { + const map = createMap(); + + const zoom = jest.fn(); + map.on('zoomstart', zoom); + + simulate.dblclick(map.getCanvasContainer()); + map._renderTaskQueue.run(); + + expect(zoom).toHaveBeenCalled(); + + map.remove(); + }); + + test('DoubleClickZoomHandler does not zoom if preventDefault is called on the dblclick event', () => { + const map = createMap(); + + map.on('dblclick', (e) => e.preventDefault()); + + const zoom = jest.fn(); + map.on('zoomstart', zoom); + + simulate.dblclick(map.getCanvasContainer()); + map._renderTaskQueue.run(); + + expect(zoom).not.toHaveBeenCalled(); + + map.remove(); + }); + + test('DoubleClickZoomHandler zooms on double tap if touchstart events are < 300ms apart', async () => { + const map = createMap(); + + const zoom = jest.fn(); + map.on('zoomstart', zoom); + + await simulateDoubleTap(map, 100); + expect(zoom).toHaveBeenCalled(); + + map.remove(); + }); + + test('DoubleClickZoomHandler does not zoom on double tap if touchstart events are > 500ms apart', async () => { + const map = createMap(); + + const zoom = jest.fn(); + map.on('zoom', zoom); + + await simulateDoubleTap(map, 500); + + expect(zoom).not.toHaveBeenCalled(); + map.remove(); + }); + + test('DoubleClickZoomHandler does not zoom on double tap if touchstart events are in different locations', async () => { + const map = createMap(); + + const zoom = jest.fn(); + map.on('zoom', zoom); + + const canvas = map.getCanvasContainer(); + + await new Promise((resolve) => { + simulate.touchstart(canvas, { touches: [{ clientX: 0, clientY: 0 }] }); + simulate.touchend(canvas); + setTimeout(() => { + simulate.touchstart(canvas, { touches: [{ clientX: 30.5, clientY: 30.5 }] }); + simulate.touchend(canvas); + map._renderTaskQueue.run(); + resolve(undefined); + }, 100); + }); + + expect(zoom).not.toHaveBeenCalled(); + + map.remove(); + }); + + test('DoubleClickZoomHandler zooms on the second touchend event of a double tap', () => { + const map = createMap(); + + const zoom = jest.fn(); + map.on('zoomstart', zoom); + + const canvas = map.getCanvasContainer(); + const touchOptions = { touches: [{ target: canvas, clientX: 0.5, clientY: 0.5 }] }; + + simulate.touchstart(canvas, touchOptions); + simulate.touchend(canvas); + simulate.touchstart(canvas, touchOptions); + map._renderTaskQueue.run(); + map._renderTaskQueue.run(); + expect(zoom).not.toHaveBeenCalled(); + + simulate.touchcancel(canvas); + simulate.touchend(canvas); + map._renderTaskQueue.run(); + expect(zoom).not.toHaveBeenCalled(); + + simulate.touchstart(canvas, touchOptions); + simulate.touchend(canvas); + simulate.touchstart(canvas, touchOptions); + map._renderTaskQueue.run(); + expect(zoom).not.toHaveBeenCalled(); + + simulate.touchend(canvas); + map._renderTaskQueue.run(); + + expect(zoom).toHaveBeenCalled(); + }); + + test('DoubleClickZoomHandler does not zoom on double tap if second touchend is >300ms after first touchstart', async () => { + const map = createMap(); + + const zoom = jest.fn(); + map.on('zoom', zoom); + + const canvas = map.getCanvasContainer(); + + await new Promise((resolve) => { + simulate.touchstart(canvas); + simulate.touchend(canvas); + simulate.touchstart(canvas); + setTimeout(() => { + simulate.touchend(canvas); + map._renderTaskQueue.run(); + resolve(undefined); + }, 300); + }); + + expect(zoom).not.toHaveBeenCalled(); + }); +}); diff --git a/packages/map/__tests__/handler/drag_pan.spec.ts b/packages/map/__tests__/handler/drag_pan.spec.ts new file mode 100644 index 00000000000..4edb1fa5c72 --- /dev/null +++ b/packages/map/__tests__/handler/drag_pan.spec.ts @@ -0,0 +1,471 @@ +import type { MapOptions } from '../../src/map/map'; +import { Map } from '../../src/map/map'; +import { DOM } from '../../src/map/util/dom'; +import simulate from '../libs/simulate_interaction'; +import { beforeMapTest } from '../libs/util'; + +function createMap(clickTolerance?, dragPan?) { + return new Map({ + container: DOM.create('div', '', window.document.body), + clickTolerance: clickTolerance || 0, + dragPan: dragPan || true, + } as any as MapOptions); +} + +beforeEach(() => { + beforeMapTest(); +}); + +// MouseEvent.buttons = 1 // left button +const buttons = 1; + +describe('drag_pan', () => { + test('DragPanHandler fires dragstart, drag, and dragend events at appropriate times in response to a mouse-triggered drag', () => { + const map = createMap(); + + const dragstart = jest.fn(); + const drag = jest.fn(); + const dragend = jest.fn(); + + map.on('dragstart', dragstart); + map.on('drag', drag); + map.on('dragend', dragend); + + simulate.mousedown(map.getCanvasContainer()); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(0); + expect(drag).toHaveBeenCalledTimes(0); + expect(dragend).toHaveBeenCalledTimes(0); + + simulate.mousemove(map.getCanvasContainer(), { buttons, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(1); + expect(drag).toHaveBeenCalledTimes(1); + expect(dragend).toHaveBeenCalledTimes(0); + + simulate.mouseup(map.getCanvasContainer()); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(1); + expect(drag).toHaveBeenCalledTimes(1); + expect(dragend).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test('DragPanHandler captures mousemove events during a mouse-triggered drag (receives them even if they occur outside the map)', () => { + const map = createMap(); + + const dragstart = jest.fn(); + const drag = jest.fn(); + const dragend = jest.fn(); + + map.on('dragstart', dragstart); + map.on('drag', drag); + map.on('dragend', dragend); + + simulate.mousedown(map.getCanvasContainer()); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(0); + expect(drag).toHaveBeenCalledTimes(0); + expect(dragend).toHaveBeenCalledTimes(0); + + simulate.mousemove(window.document.body, { buttons, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(1); + expect(drag).toHaveBeenCalledTimes(1); + expect(dragend).toHaveBeenCalledTimes(0); + + simulate.mouseup(map.getCanvasContainer()); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(1); + expect(drag).toHaveBeenCalledTimes(1); + expect(dragend).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test('DragPanHandler fires dragstart, drag, and dragend events at appropriate times in response to a touch-triggered drag', () => { + const map = createMap(); + const target = map.getCanvasContainer(); + + const dragstart = jest.fn(); + const drag = jest.fn(); + const dragend = jest.fn(); + + map.on('dragstart', dragstart); + map.on('drag', drag); + map.on('dragend', dragend); + + simulate.touchstart(map.getCanvasContainer(), { + touches: [{ target, clientX: 0, clientY: 0 }], + }); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(0); + expect(drag).toHaveBeenCalledTimes(0); + expect(dragend).toHaveBeenCalledTimes(0); + + simulate.touchmove(map.getCanvasContainer(), { + touches: [{ target, clientX: 10, clientY: 10 }], + }); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(1); + expect(drag).toHaveBeenCalledTimes(1); + expect(dragend).toHaveBeenCalledTimes(0); + + simulate.touchend(map.getCanvasContainer()); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(1); + expect(drag).toHaveBeenCalledTimes(1); + expect(dragend).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test('DragPanHandler prevents mousemove events from firing during a drag (#1555)', () => { + const map = createMap(); + + const mousemove = jest.fn(); + map.on('mousemove', mousemove); + + simulate.mousedown(map.getCanvasContainer()); + map._renderTaskQueue.run(); + + simulate.mousemove(map.getCanvasContainer(), { buttons, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + + simulate.mouseup(map.getCanvasContainer()); + map._renderTaskQueue.run(); + + expect(mousemove).not.toHaveBeenCalled(); + + map.remove(); + }); + + test('DragPanHandler ends a mouse-triggered drag if the window blurs', () => { + const map = createMap(); + + const dragend = jest.fn(); + map.on('dragend', dragend); + + simulate.mousedown(map.getCanvasContainer()); + map._renderTaskQueue.run(); + + simulate.mousemove(map.getCanvasContainer(), { buttons, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + + simulate.blur(window); + expect(dragend).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test('DragPanHandler ends a touch-triggered drag if the window blurs', () => { + const map = createMap(); + const target = map.getCanvasContainer(); + + const dragend = jest.fn(); + map.on('dragend', dragend); + + simulate.touchstart(map.getCanvasContainer(), { + touches: [{ target, clientX: 0, clientY: 0 }], + }); + map._renderTaskQueue.run(); + + simulate.touchmove(map.getCanvasContainer(), { + touches: [{ target, clientX: 10, clientY: 10 }], + }); + map._renderTaskQueue.run(); + + simulate.blur(window); + expect(dragend).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test('DragPanHandler requests a new render frame after each mousemove event', () => { + const map = createMap(); + const requestFrame = jest.spyOn(map.handlers, '_requestFrame'); + + simulate.mousedown(map.getCanvasContainer()); + simulate.mousemove(map.getCanvasContainer(), { buttons, clientX: 10, clientY: 10 }); + expect(requestFrame).toHaveBeenCalled(); + + map._renderTaskQueue.run(); + + // https://github.com/mapbox/mapbox-gl-js/issues/6063 + requestFrame.mockReset(); + simulate.mousemove(map.getCanvasContainer(), { buttons, clientX: 20, clientY: 20 }); + expect(requestFrame).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test('DragPanHandler can interleave with another handler', () => { + // https://github.com/mapbox/mapbox-gl-js/issues/6106 + const map = createMap(); + + const dragstart = jest.fn(); + const drag = jest.fn(); + const dragend = jest.fn(); + + map.on('dragstart', dragstart); + map.on('drag', drag); + map.on('dragend', dragend); + + simulate.mousedown(map.getCanvasContainer()); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(0); + expect(drag).toHaveBeenCalledTimes(0); + expect(dragend).toHaveBeenCalledTimes(0); + + simulate.mousemove(map.getCanvasContainer(), { buttons, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(1); + expect(drag).toHaveBeenCalledTimes(1); + expect(dragend).toHaveBeenCalledTimes(0); + + // simulate a scroll zoom + simulate.wheel(map.getCanvasContainer(), { + type: 'wheel', + deltaY: -simulate.magicWheelZoomDelta, + }); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(1); + expect(drag).toHaveBeenCalledTimes(1); + expect(dragend).toHaveBeenCalledTimes(0); + + simulate.mousemove(map.getCanvasContainer(), { buttons, clientX: 20, clientY: 20 }); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(1); + expect(drag).toHaveBeenCalledTimes(2); + expect(dragend).toHaveBeenCalledTimes(0); + + simulate.mouseup(map.getCanvasContainer()); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(1); + expect(drag).toHaveBeenCalledTimes(2); + expect(dragend).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + ['ctrl', 'shift'].forEach((modifier) => { + test(`DragPanHandler does not begin a drag if the ${modifier} key is down on mousedown`, () => { + const map = createMap(); + expect(map.dragRotate.isEnabled()).toBeTruthy(); + + const dragstart = jest.fn(); + const drag = jest.fn(); + const dragend = jest.fn(); + + map.on('dragstart', dragstart); + map.on('drag', drag); + map.on('dragend', dragend); + + simulate.mousedown(map.getCanvasContainer(), { buttons, [`${modifier}Key`]: true }); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(0); + expect(drag).toHaveBeenCalledTimes(0); + expect(dragend).toHaveBeenCalledTimes(0); + + simulate.mousemove(map.getCanvasContainer(), { + buttons, + [`${modifier}Key`]: true, + clientX: 10, + clientY: 10, + }); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(0); + expect(drag).toHaveBeenCalledTimes(0); + expect(dragend).toHaveBeenCalledTimes(0); + + simulate.mouseup(map.getCanvasContainer(), { [`${modifier}Key`]: true }); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(0); + expect(drag).toHaveBeenCalledTimes(0); + expect(dragend).toHaveBeenCalledTimes(0); + + map.remove(); + }); + + test(`DragPanHandler still ends a drag if the ${modifier} key is down on mouseup`, () => { + const map = createMap(); + expect(map.dragRotate.isEnabled()).toBeTruthy(); + + const dragstart = jest.fn(); + const drag = jest.fn(); + const dragend = jest.fn(); + + map.on('dragstart', dragstart); + map.on('drag', drag); + map.on('dragend', dragend); + + simulate.mousedown(map.getCanvasContainer()); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(0); + expect(drag).toHaveBeenCalledTimes(0); + expect(dragend).toHaveBeenCalledTimes(0); + + simulate.mouseup(map.getCanvasContainer(), { [`${modifier}Key`]: true }); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(0); + expect(drag).toHaveBeenCalledTimes(0); + expect(dragend).toHaveBeenCalledTimes(0); + + simulate.mousemove(map.getCanvasContainer(), { buttons, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(0); + expect(drag).toHaveBeenCalledTimes(0); + expect(dragend).toHaveBeenCalledTimes(0); + + map.remove(); + }); + }); + + test('DragPanHandler does not begin a drag on right button mousedown', () => { + const map = createMap(); + map.dragRotate.disable(); + + const dragstart = jest.fn(); + const drag = jest.fn(); + const dragend = jest.fn(); + + map.on('dragstart', dragstart); + map.on('drag', drag); + map.on('dragend', dragend); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2 }); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(0); + expect(drag).toHaveBeenCalledTimes(0); + expect(dragend).toHaveBeenCalledTimes(0); + + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(0); + expect(drag).toHaveBeenCalledTimes(0); + expect(dragend).toHaveBeenCalledTimes(0); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 2 }); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(0); + expect(drag).toHaveBeenCalledTimes(0); + expect(dragend).toHaveBeenCalledTimes(0); + + map.remove(); + }); + + test('DragPanHandler does not end a drag on right button mouseup', () => { + const map = createMap(); + map.dragRotate.disable(); + + const dragstart = jest.fn(); + const drag = jest.fn(); + const dragend = jest.fn(); + + map.on('dragstart', dragstart); + map.on('drag', drag); + map.on('dragend', dragend); + + simulate.mousedown(map.getCanvasContainer()); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(0); + expect(drag).toHaveBeenCalledTimes(0); + expect(dragend).toHaveBeenCalledTimes(0); + + simulate.mousemove(map.getCanvasContainer(), { buttons, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(1); + expect(drag).toHaveBeenCalledTimes(1); + expect(dragend).toHaveBeenCalledTimes(0); + + simulate.mousedown(map.getCanvasContainer(), { buttons: buttons + 2, button: 2 }); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(1); + expect(drag).toHaveBeenCalledTimes(1); + expect(dragend).toHaveBeenCalledTimes(0); + + simulate.mouseup(map.getCanvasContainer(), { buttons, button: 2 }); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(1); + expect(drag).toHaveBeenCalledTimes(1); + expect(dragend).toHaveBeenCalledTimes(0); + + simulate.mousemove(map.getCanvasContainer(), { buttons, clientX: 20, clientY: 20 }); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(1); + expect(drag).toHaveBeenCalledTimes(2); + expect(dragend).toHaveBeenCalledTimes(0); + + simulate.mouseup(map.getCanvasContainer()); + map._renderTaskQueue.run(); + expect(dragstart).toHaveBeenCalledTimes(1); + expect(drag).toHaveBeenCalledTimes(2); + expect(dragend).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test('DragPanHandler does not begin a drag if preventDefault is called on the mousedown event', () => { + const map = createMap(); + + map.on('mousedown', (e) => e.preventDefault()); + + const dragstart = jest.fn(); + const drag = jest.fn(); + const dragend = jest.fn(); + + map.on('dragstart', dragstart); + map.on('drag', drag); + map.on('dragend', dragend); + + simulate.mousedown(map.getCanvasContainer()); + map._renderTaskQueue.run(); + + simulate.mousemove(map.getCanvasContainer(), { buttons, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + + simulate.mouseup(map.getCanvasContainer()); + map._renderTaskQueue.run(); + + expect(dragstart).toHaveBeenCalledTimes(0); + expect(drag).toHaveBeenCalledTimes(0); + expect(dragend).toHaveBeenCalledTimes(0); + + map.remove(); + }); + + test('DragPanHandler does not begin a drag if preventDefault is called on the touchstart event', () => { + const map = createMap(); + const target = map.getCanvasContainer(); + + map.on('touchstart', (e) => e.preventDefault()); + + const dragstart = jest.fn(); + const drag = jest.fn(); + const dragend = jest.fn(); + + map.on('dragstart', dragstart); + map.on('drag', drag); + map.on('dragend', dragend); + + simulate.touchstart(map.getCanvasContainer(), { + touches: [{ target, clientX: 0, clientY: 0 }], + }); + map._renderTaskQueue.run(); + + simulate.touchmove(map.getCanvasContainer(), { + touches: [{ target, clientX: 10, clientY: 10 }], + }); + map._renderTaskQueue.run(); + + simulate.touchend(map.getCanvasContainer()); + map._renderTaskQueue.run(); + + expect(dragstart).toHaveBeenCalledTimes(0); + expect(drag).toHaveBeenCalledTimes(0); + expect(dragend).toHaveBeenCalledTimes(0); + + map.remove(); + }); +}); diff --git a/packages/map/__tests__/handler/drag_rotate.spec.ts b/packages/map/__tests__/handler/drag_rotate.spec.ts new file mode 100644 index 00000000000..93fa8020f6c --- /dev/null +++ b/packages/map/__tests__/handler/drag_rotate.spec.ts @@ -0,0 +1,906 @@ +import { Map } from '../../src/map/map'; +import { browser } from '../../src/map/util/browser'; +import { DOM } from '../../src/map/util/dom'; +import { extend } from '../../src/map/util/util'; +import simulate from '../libs/simulate_interaction'; + +import { beforeMapTest } from '../libs/util'; + +function createMap(options?) { + return new Map(extend({ container: DOM.create('div', '', window.document.body) }, options)); +} + +beforeEach(() => { + beforeMapTest(); +}); + +describe('drag rotate', () => { + test('DragRotateHandler#isActive', () => { + const map = createMap(); + + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockReturnValue(0); + + expect(map.dragRotate.isActive()).toBe(false); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2 }); + map._renderTaskQueue.run(); + expect(map.dragRotate.isActive()).toBe(false); + + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + expect(map.dragRotate.isActive()).toBe(true); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 2 }); + map._renderTaskQueue.run(); + expect(map.dragRotate.isActive()).toBe(false); + + map.remove(); + }); + + test('DragRotateHandler fires rotatestart, rotate, and rotateend events at appropriate times in response to a right-click drag', () => { + const map = createMap(); + + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockReturnValue(0); + + const rotatestart = jest.fn(); + const rotate = jest.fn(); + const rotateend = jest.fn(); + + map.on('rotatestart', rotatestart); + map.on('rotate', rotate); + map.on('rotateend', rotateend); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2 }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(0); + expect(rotate).toHaveBeenCalledTimes(0); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(1); + expect(rotate).toHaveBeenCalledTimes(1); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 2 }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(1); + expect(rotate).toHaveBeenCalledTimes(1); + expect(rotateend).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test('DragRotateHandler stops firing events after mouseup', () => { + const map = createMap(); + + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockReturnValue(0); + + const spy = jest.fn(); + map.on('rotatestart', spy); + map.on('rotate', spy); + map.on('rotateend', spy); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2 }); + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 2 }); + map._renderTaskQueue.run(); + expect(spy).toHaveBeenCalledTimes(3); + + spy.mockReset(); + simulate.mousemove(map.getCanvasContainer(), { buttons: 0, clientX: 20, clientY: 20 }); + map._renderTaskQueue.run(); + expect(spy).toHaveBeenCalledTimes(0); + + map.remove(); + }); + + test('DragRotateHandler fires rotatestart, rotate, and rotateend events at appropriate times in response to a control-left-click drag', () => { + const map = createMap(); + + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockReturnValue(0); + + const rotatestart = jest.fn(); + const rotate = jest.fn(); + const rotateend = jest.fn(); + + map.on('rotatestart', rotatestart); + map.on('rotate', rotate); + map.on('rotateend', rotateend); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 1, button: 0, ctrlKey: true }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(0); + expect(rotate).toHaveBeenCalledTimes(0); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.mousemove(map.getCanvasContainer(), { + buttons: 1, + ctrlKey: true, + clientX: 10, + clientY: 10, + }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(1); + expect(rotate).toHaveBeenCalledTimes(1); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 0, ctrlKey: true }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(1); + expect(rotate).toHaveBeenCalledTimes(1); + expect(rotateend).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test('DragRotateHandler pitches in response to a right-click drag by default', () => { + const map = createMap(); + + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockReturnValue(0); + + const pitchstart = jest.fn(); + const pitch = jest.fn(); + const pitchend = jest.fn(); + + map.on('pitchstart', pitchstart); + map.on('pitch', pitch); + map.on('pitchend', pitchend); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2 }); + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: -10 }); + map._renderTaskQueue.run(); + expect(pitchstart).toHaveBeenCalledTimes(1); + expect(pitch).toHaveBeenCalledTimes(1); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 2 }); + map._renderTaskQueue.run(); + expect(pitchend).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test("DragRotateHandler doesn't fire pitch event when rotating only", () => { + const map = createMap(); + + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockReturnValue(0); + + const pitchstart = jest.fn(); + const pitch = jest.fn(); + const pitchend = jest.fn(); + + map.on('pitchstart', pitchstart); + map.on('pitch', pitch); + map.on('pitchend', pitchend); + + simulate.mousedown(map.getCanvasContainer(), { + buttons: 2, + button: 2, + clientX: 0, + clientY: 10, + }); + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + expect(pitchstart).toHaveBeenCalledTimes(0); + expect(pitch).toHaveBeenCalledTimes(0); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 2 }); + expect(pitchend).toHaveBeenCalledTimes(0); + + map.remove(); + }); + + test('DragRotateHandler pitches in response to a control-left-click drag', () => { + const map = createMap(); + + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockReturnValue(0); + + const pitchstart = jest.fn(); + const pitch = jest.fn(); + const pitchend = jest.fn(); + + map.on('pitchstart', pitchstart); + map.on('pitch', pitch); + map.on('pitchend', pitchend); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 1, button: 0, ctrlKey: true }); + simulate.mousemove(map.getCanvasContainer(), { + buttons: 1, + ctrlKey: true, + clientX: 10, + clientY: -10, + }); + map._renderTaskQueue.run(); + expect(pitchstart).toHaveBeenCalledTimes(1); + expect(pitch).toHaveBeenCalledTimes(1); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 0, ctrlKey: true }); + map._renderTaskQueue.run(); + expect(pitchend).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test('DragRotateHandler does not pitch if given pitchWithRotate: false', () => { + const map = createMap({ pitchWithRotate: false }); + + const spy = jest.fn(); + + map.on('pitchstart', spy); + map.on('pitch', spy); + map.on('pitchend', spy); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2 }); + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 2 }); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 1, button: 0, ctrlKey: true }); + simulate.mousemove(map.getCanvasContainer(), { + buttons: 1, + ctrlKey: true, + clientX: 10, + clientY: 10, + }); + map._renderTaskQueue.run(); + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 0, ctrlKey: true }); + + expect(spy).not.toHaveBeenCalled(); + + map.remove(); + }); + + test('DragRotateHandler does not rotate or pitch when disabled', () => { + const map = createMap(); + + map.dragRotate.disable(); + + const spy = jest.fn(); + + map.on('rotatestart', spy); + map.on('rotate', spy); + map.on('rotateend', spy); + map.on('pitchstart', spy); + map.on('pitch', spy); + map.on('pitchend', spy); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2 }); + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 2 }); + + expect(spy).not.toHaveBeenCalled(); + + map.remove(); + }); + + test('DragRotateHandler ensures that map.isMoving() returns true during drag', () => { + // The bearingSnap option here ensures that the moveend event is sent synchronously. + const map = createMap({ bearingSnap: 0 }); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2 }); + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + expect(map.isMoving()).toBeTruthy(); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 2 }); + map._renderTaskQueue.run(); + expect(!map.isMoving()).toBeTruthy(); + + map.remove(); + }); + + test('DragRotateHandler fires move events', () => { + // The bearingSnap option here ensures that the moveend event is sent synchronously. + const map = createMap({ bearingSnap: 0 }); + + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockReturnValue(0); + + const movestart = jest.fn(); + const move = jest.fn(); + const moveend = jest.fn(); + + map.on('movestart', movestart); + map.on('move', move); + map.on('moveend', moveend); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2 }); + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + expect(movestart).toHaveBeenCalledTimes(1); + expect(move).toHaveBeenCalledTimes(1); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 2 }); + map._renderTaskQueue.run(); + expect(moveend).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test("DragRotateHandler doesn't fire rotate event when pitching only", () => { + // The bearingSnap option here ensures that the moveend event is sent synchronously. + const map = createMap({ bearingSnap: 0 }); + + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockReturnValue(0); + + const rotatestart = jest.fn(); + const rotate = jest.fn(); + const pitch = jest.fn(); + const rotateend = jest.fn(); + + map.on('rotatestart', rotatestart); + map.on('rotate', rotate); + map.on('pitch', pitch); + map.on('rotateend', rotateend); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2, clientX: 0, clientY: 0 }); + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 0, clientY: -10 }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(0); + expect(rotate).toHaveBeenCalledTimes(0); + expect(pitch).toHaveBeenCalledTimes(1); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 2 }); + expect(rotateend).toHaveBeenCalledTimes(0); + + map.remove(); + }); + + test('DragRotateHandler includes originalEvent property in triggered events', () => { + // The bearingSnap option here ensures that the moveend event is sent synchronously. + const map = createMap({ bearingSnap: 0 }); + + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockReturnValue(0); + + const rotatestart = jest.fn(); + const rotate = jest.fn(); + const rotateend = jest.fn(); + map.on('rotatestart', rotatestart); + map.on('rotate', rotate); + map.on('rotateend', rotateend); + + const pitchstart = jest.fn(); + const pitch = jest.fn(); + const pitchend = jest.fn(); + map.on('pitchstart', pitchstart); + map.on('pitch', pitch); + map.on('pitchend', pitchend); + + const movestart = jest.fn(); + const move = jest.fn(); + const moveend = jest.fn(); + map.on('movestart', movestart); + map.on('move', move); + map.on('moveend', moveend); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2 }); + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: -10 }); + map._renderTaskQueue.run(); + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 2 }); + map._renderTaskQueue.run(); + + expect(rotatestart.mock.calls[0][0].originalEvent.type).toBeTruthy(); + expect(pitchstart.mock.calls[0][0].originalEvent.type).toBeTruthy(); + expect(movestart.mock.calls[0][0].originalEvent.type).toBeTruthy(); + + expect(rotate.mock.calls[0][0].originalEvent.type).toBeTruthy(); + expect(pitch.mock.calls[0][0].originalEvent.type).toBeTruthy(); + expect(move.mock.calls[0][0].originalEvent.type).toBeTruthy(); + + expect(rotateend.mock.calls[0][0].originalEvent.type).toBeTruthy(); + expect(pitchend.mock.calls[0][0].originalEvent.type).toBeTruthy(); + expect(moveend.mock.calls[0][0].originalEvent.type).toBeTruthy(); + + map.remove(); + }); + + test('DragRotateHandler responds to events on the canvas container (#1301)', () => { + const map = createMap(); + + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockReturnValue(0); + + const rotatestart = jest.fn(); + const rotate = jest.fn(); + const rotateend = jest.fn(); + + map.on('rotatestart', rotatestart); + map.on('rotate', rotate); + map.on('rotateend', rotateend); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2 }); + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(1); + expect(rotate).toHaveBeenCalledTimes(1); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 2 }); + map._renderTaskQueue.run(); + expect(rotateend).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test('DragRotateHandler prevents mousemove events from firing during a drag (#1555)', () => { + const map = createMap(); + + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockReturnValue(0); + + const mousemove = jest.fn(); + map.on('mousemove', mousemove); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2 }); + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 100, clientY: 100 }); + map._renderTaskQueue.run(); + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 2 }); + + expect(mousemove).not.toHaveBeenCalled(); + + map.remove(); + }); + + test('DragRotateHandler ends a control-left-click drag on mouseup even when the control key was previously released (#1888)', () => { + const map = createMap(); + + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockReturnValue(0); + + const rotatestart = jest.fn(); + const rotate = jest.fn(); + const rotateend = jest.fn(); + + map.on('rotatestart', rotatestart); + map.on('rotate', rotate); + map.on('rotateend', rotateend); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 1, button: 0, ctrlKey: true }); + simulate.mousemove(map.getCanvasContainer(), { + buttons: 1, + ctrlKey: true, + clientX: 10, + clientY: 10, + }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(1); + expect(rotate).toHaveBeenCalledTimes(1); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 0, ctrlKey: false }); + map._renderTaskQueue.run(); + expect(rotateend).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test('DragRotateHandler ends rotation if the window blurs (#3389)', () => { + const map = createMap(); + + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockReturnValue(0); + + const rotatestart = jest.fn(); + const rotate = jest.fn(); + const rotateend = jest.fn(); + + map.on('rotatestart', rotatestart); + map.on('rotate', rotate); + map.on('rotateend', rotateend); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2 }); + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(1); + expect(rotate).toHaveBeenCalledTimes(1); + + simulate.blur(window); + expect(rotateend).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test('DragRotateHandler requests a new render frame after each mousemove event', () => { + const map = createMap(); + const requestRenderFrame = jest.spyOn(map.handlers, '_requestFrame'); + + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockReturnValue(0); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2 }); + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: 10 }); + expect(requestRenderFrame).toHaveBeenCalled(); + + map._renderTaskQueue.run(); + + // https://github.com/mapbox/mapbox-gl-js/issues/6063 + requestRenderFrame.mockReset(); + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 20, clientY: 20 }); + expect(requestRenderFrame).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test('DragRotateHandler can interleave with another handler', () => { + // https://github.com/mapbox/mapbox-gl-js/issues/6106 + const map = createMap(); + + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockReturnValue(0); + + const rotatestart = jest.fn(); + const rotate = jest.fn(); + const rotateend = jest.fn(); + + map.on('rotatestart', rotatestart); + map.on('rotate', rotate); + map.on('rotateend', rotateend); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2 }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(0); + expect(rotate).toHaveBeenCalledTimes(0); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(1); + expect(rotate).toHaveBeenCalledTimes(1); + expect(rotateend).toHaveBeenCalledTimes(0); + + // simulates another handler taking over + // simulate a scroll zoom + simulate.wheel(map.getCanvasContainer(), { + type: 'wheel', + deltaY: -simulate.magicWheelZoomDelta, + }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(1); + expect(rotate).toHaveBeenCalledTimes(1); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 20, clientY: 20 }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(1); + expect(rotate).toHaveBeenCalledTimes(2); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 2 }); + map._renderTaskQueue.run(); + // Ignore second rotatestart triggered by inertia + expect(rotate).toHaveBeenCalledTimes(2); + expect(rotateend).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test('DragRotateHandler does not begin a drag on left-button mousedown without the control key', () => { + const map = createMap(); + map.dragPan.disable(); + + const rotatestart = jest.fn(); + const rotate = jest.fn(); + const rotateend = jest.fn(); + + map.on('rotatestart', rotatestart); + map.on('rotate', rotate); + map.on('rotateend', rotateend); + + simulate.mousedown(map.getCanvasContainer()); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(0); + expect(rotate).toHaveBeenCalledTimes(0); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.mousemove(map.getCanvasContainer(), { clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(0); + expect(rotate).toHaveBeenCalledTimes(0); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.mouseup(map.getCanvasContainer()); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(0); + expect(rotate).toHaveBeenCalledTimes(0); + expect(rotateend).toHaveBeenCalledTimes(0); + + map.remove(); + }); + + test('DragRotateHandler does not end a right-button drag on left-button mouseup', () => { + const map = createMap(); + map.dragPan.disable(); + + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockReturnValue(0); + + const rotatestart = jest.fn(); + const rotate = jest.fn(); + const rotateend = jest.fn(); + + map.on('rotatestart', rotatestart); + map.on('rotate', rotate); + map.on('rotateend', rotateend); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2 }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(0); + expect(rotate).toHaveBeenCalledTimes(0); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(1); + expect(rotate).toHaveBeenCalledTimes(1); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 3, button: 0 }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(1); + expect(rotate).toHaveBeenCalledTimes(1); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 2, button: 0 }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(1); + expect(rotate).toHaveBeenCalledTimes(1); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 20, clientY: 20 }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(1); + expect(rotate).toHaveBeenCalledTimes(2); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 2 }); + map._renderTaskQueue.run(); + // Ignore second rotatestart triggered by inertia + expect(rotate).toHaveBeenCalledTimes(2); + expect(rotateend).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test('DragRotateHandler does not end a control-left-button drag on right-button mouseup', () => { + const map = createMap(); + map.dragPan.disable(); + + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockReturnValue(0); + + const rotatestart = jest.fn(); + const rotate = jest.fn(); + const rotateend = jest.fn(); + + map.on('rotatestart', rotatestart); + map.on('rotate', rotate); + map.on('rotateend', rotateend); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 1, button: 0, ctrlKey: true }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(0); + expect(rotate).toHaveBeenCalledTimes(0); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.mousemove(map.getCanvasContainer(), { + buttons: 1, + ctrlKey: true, + clientX: 10, + clientY: 10, + }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(1); + expect(rotate).toHaveBeenCalledTimes(1); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 3, button: 2, ctrlKey: true }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(1); + expect(rotate).toHaveBeenCalledTimes(1); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 1, button: 2, ctrlKey: true }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(1); + expect(rotate).toHaveBeenCalledTimes(1); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.mousemove(map.getCanvasContainer(), { + buttons: 1, + ctrlKey: true, + clientX: 20, + clientY: 20, + }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(1); + expect(rotate).toHaveBeenCalledTimes(2); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 0, ctrlKey: true }); + map._renderTaskQueue.run(); + // Ignore second rotatestart triggered by inertia + expect(rotate).toHaveBeenCalledTimes(2); + expect(rotateend).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test('DragRotateHandler does not begin a drag if preventDefault is called on the mousedown event', () => { + const map = createMap(); + + map.on('mousedown', (e) => e.preventDefault()); + + const rotatestart = jest.fn(); + const rotate = jest.fn(); + const rotateend = jest.fn(); + + map.on('rotatestart', rotatestart); + map.on('rotate', rotate); + map.on('rotateend', rotateend); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2 }); + map._renderTaskQueue.run(); + + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 2 }); + map._renderTaskQueue.run(); + + expect(rotatestart).toHaveBeenCalledTimes(0); + expect(rotate).toHaveBeenCalledTimes(0); + expect(rotateend).toHaveBeenCalledTimes(0); + + map.remove(); + }); + + test('DragRotateHandler can be disabled after mousedown (#2419)', () => { + const map = createMap(); + + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockReturnValue(0); + + const rotatestart = jest.fn(); + const rotate = jest.fn(); + const rotateend = jest.fn(); + + map.on('rotatestart', rotatestart); + map.on('rotate', rotate); + map.on('rotateend', rotateend); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2 }); + map._renderTaskQueue.run(); + + map.dragRotate.disable(); + + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + + expect(rotatestart).toHaveBeenCalledTimes(0); + expect(rotate).toHaveBeenCalledTimes(0); + expect(rotateend).toHaveBeenCalledTimes(0); + expect(map.isMoving()).toBe(false); + expect(map.dragRotate.isEnabled()).toBe(false); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 2 }); + map._renderTaskQueue.run(); + + expect(rotatestart).toHaveBeenCalledTimes(0); + expect(rotate).toHaveBeenCalledTimes(0); + expect(rotateend).toHaveBeenCalledTimes(0); + expect(map.isMoving()).toBe(false); + expect(map.dragRotate.isEnabled()).toBe(false); + + map.remove(); + }); + + test('DragRotateHandler does not begin rotation on spurious mousemove events', () => { + const map = createMap(); + + const rotatestart = jest.fn(); + const rotate = jest.fn(); + const rotateend = jest.fn(); + + map.on('rotatestart', rotatestart); + map.on('rotate', rotate); + map.on('rotateend', rotateend); + + simulate.mousedown(map.getCanvasContainer(), { + buttons: 2, + button: 2, + clientX: 10, + clientY: 10, + }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(0); + expect(rotate).toHaveBeenCalledTimes(0); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(0); + expect(rotate).toHaveBeenCalledTimes(0); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 2, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(0); + expect(rotate).toHaveBeenCalledTimes(0); + expect(rotateend).toHaveBeenCalledTimes(0); + + map.remove(); + }); + + test('DragRotateHandler does not begin a mouse drag if moved less than click tolerance', () => { + const map = createMap({ clickTolerance: 4 }); + + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockReturnValue(0); + + const rotatestart = jest.fn(); + const rotate = jest.fn(); + const rotateend = jest.fn(); + const pitchstart = jest.fn(); + const pitch = jest.fn(); + const pitchend = jest.fn(); + + map.on('rotatestart', rotatestart); + map.on('rotate', rotate); + map.on('rotateend', rotateend); + map.on('pitchstart', pitchstart); + map.on('pitch', pitch); + map.on('pitchend', pitchend); + + simulate.mousedown(map.getCanvasContainer(), { + buttons: 2, + button: 2, + clientX: 10, + clientY: 10, + }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(0); + expect(rotate).toHaveBeenCalledTimes(0); + expect(rotateend).toHaveBeenCalledTimes(0); + expect(pitchstart).toHaveBeenCalledTimes(0); + expect(pitch).toHaveBeenCalledTimes(0); + expect(pitchend).toHaveBeenCalledTimes(0); + + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 13, clientY: 10 }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(0); + expect(rotate).toHaveBeenCalledTimes(0); + expect(rotateend).toHaveBeenCalledTimes(0); + expect(pitchstart).toHaveBeenCalledTimes(0); + expect(pitch).toHaveBeenCalledTimes(0); + expect(pitchend).toHaveBeenCalledTimes(0); + + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: 13 }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(0); + expect(rotate).toHaveBeenCalledTimes(0); + expect(rotateend).toHaveBeenCalledTimes(0); + expect(pitchstart).toHaveBeenCalledTimes(0); + expect(pitch).toHaveBeenCalledTimes(0); + expect(pitchend).toHaveBeenCalledTimes(0); + + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 14, clientY: 10 - 4 }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(1); + expect(rotate).toHaveBeenCalledTimes(1); + expect(rotateend).toHaveBeenCalledTimes(0); + expect(pitchstart).toHaveBeenCalledTimes(1); + expect(pitch).toHaveBeenCalledTimes(1); + expect(pitchend).toHaveBeenCalledTimes(0); + + map.remove(); + }); +}); diff --git a/packages/map/__tests__/handler/keyboard.spec.ts b/packages/map/__tests__/handler/keyboard.spec.ts new file mode 100644 index 00000000000..3184bf6e458 --- /dev/null +++ b/packages/map/__tests__/handler/keyboard.spec.ts @@ -0,0 +1,232 @@ +import { Map } from '../../src/map/map'; +import { DOM } from '../../src/map/util/dom'; +import { extend } from '../../src/map/util/util'; +import simulate from '../libs/simulate_interaction'; +import { beforeMapTest } from '../libs/util'; + +function createMap(options?) { + return new Map( + extend( + { + container: DOM.create('div', '', window.document.body), + }, + options, + ), + ); +} + +beforeEach(() => { + beforeMapTest(); +}); + +describe('keyboard', () => { + test('KeyboardHandler responds to keydown events', () => { + const map = createMap(); + const h = map.keyboard; + const spy = jest.spyOn(h, 'keydown'); + + simulate.keydown(map.getCanvasContainer(), { keyCode: 32, key: ' ' }); + expect(h.keydown).toHaveBeenCalled(); + expect(spy.mock.calls[0][0].keyCode).toBe(32); + }); + + test('KeyboardHandler pans map in response to arrow keys', () => { + const map = createMap({ zoom: 10, center: [0, 0] }); + const spy = jest.spyOn(map, 'easeTo'); + + simulate.keydown(map.getCanvasContainer(), { keyCode: 32, key: ' ' }); + expect(map.easeTo).not.toHaveBeenCalled(); + + simulate.keydown(map.getCanvasContainer(), { keyCode: 37, key: 'ArrowLeft' }); + expect(map.easeTo).toHaveBeenCalled(); + let easeToArgs = spy.mock.calls[0][0]; + expect(easeToArgs.offset[0]).toBe(100); + expect(easeToArgs.offset[1]).toBe(-0); + + simulate.keydown(map.getCanvasContainer(), { keyCode: 39, key: 'ArrowRight' }); + expect(spy).toHaveBeenCalledTimes(2); + easeToArgs = spy.mock.calls[1][0]; + expect(easeToArgs.offset[0]).toBe(-100); + expect(easeToArgs.offset[1]).toBe(-0); + + simulate.keydown(map.getCanvasContainer(), { keyCode: 40, key: 'ArrowDown' }); + expect(spy).toHaveBeenCalledTimes(3); + easeToArgs = spy.mock.calls[2][0]; + expect(easeToArgs.offset[0]).toBe(-0); + expect(easeToArgs.offset[1]).toBe(-100); + + simulate.keydown(map.getCanvasContainer(), { keyCode: 38, key: 'ArrowUp' }); + expect(spy).toHaveBeenCalledTimes(4); + easeToArgs = spy.mock.calls[3][0]; + expect(easeToArgs.offset[0]).toBe(-0); + expect(easeToArgs.offset[1]).toBe(100); + }); + + test('KeyboardHandler pans map in response to arrow keys when disableRotation has been called', () => { + const map = createMap({ zoom: 10, center: [0, 0] }); + const spy = jest.spyOn(map, 'easeTo'); + map.keyboard.disableRotation(); + + simulate.keydown(map.getCanvasContainer(), { keyCode: 32, key: ' ' }); + expect(map.easeTo).not.toHaveBeenCalled(); + + simulate.keydown(map.getCanvasContainer(), { keyCode: 37, key: 'ArrowLeft' }); + expect(map.easeTo).toHaveBeenCalled(); + let easeToArgs = spy.mock.calls[0][0]; + expect(easeToArgs.offset[0]).toBe(100); + expect(easeToArgs.offset[1]).toBe(-0); + + simulate.keydown(map.getCanvasContainer(), { keyCode: 39, key: 'ArrowRight' }); + expect(spy).toHaveBeenCalledTimes(2); + easeToArgs = spy.mock.calls[1][0]; + expect(easeToArgs.offset[0]).toBe(-100); + expect(easeToArgs.offset[1]).toBe(-0); + + simulate.keydown(map.getCanvasContainer(), { keyCode: 40, key: 'ArrowDown' }); + expect(spy).toHaveBeenCalledTimes(3); + easeToArgs = spy.mock.calls[2][0]; + expect(easeToArgs.offset[0]).toBe(-0); + expect(easeToArgs.offset[1]).toBe(-100); + + simulate.keydown(map.getCanvasContainer(), { keyCode: 38, key: 'ArrowUp' }); + expect(spy).toHaveBeenCalledTimes(4); + easeToArgs = spy.mock.calls[3][0]; + expect(easeToArgs.offset[0]).toBe(-0); + expect(easeToArgs.offset[1]).toBe(100); + }); + + test('KeyboardHandler rotates map in response to Shift+left/right arrow keys', async () => { + const map = createMap({ zoom: 10, center: [0, 0], bearing: 0 }); + const spy = jest.spyOn(map, 'easeTo'); + + simulate.keydown(map.getCanvasContainer(), { keyCode: 32, key: ' ' }); + expect(map.easeTo).not.toHaveBeenCalled(); + + simulate.keydown(map.getCanvasContainer(), { keyCode: 37, key: 'ArrowLeft', shiftKey: true }); + expect(map.easeTo).toHaveBeenCalled(); + let easeToArgs = spy.mock.calls[0][0]; + expect(easeToArgs.bearing).toBe(-15); + expect(easeToArgs.offset[0]).toBe(-0); + + map.setBearing(0); + simulate.keydown(map.getCanvasContainer(), { keyCode: 39, key: 'ArrowRight', shiftKey: true }); + expect(spy).toHaveBeenCalledTimes(2); + easeToArgs = spy.mock.calls[1][0]; + expect(easeToArgs.bearing).toBe(15); + expect(easeToArgs.offset[0]).toBe(-0); + }); + + test('KeyboardHandler does not rotate map in response to Shift+left/right arrow keys when disableRotation has been called', async () => { + const map = createMap({ zoom: 10, center: [0, 0], bearing: 0 }); + const spy = jest.spyOn(map, 'easeTo'); + map.keyboard.disableRotation(); + + simulate.keydown(map.getCanvasContainer(), { keyCode: 32, key: ' ' }); + expect(map.easeTo).not.toHaveBeenCalled(); + + simulate.keydown(map.getCanvasContainer(), { keyCode: 37, key: 'ArrowLeft', shiftKey: true }); + expect(map.easeTo).toHaveBeenCalled(); + let easeToArgs = spy.mock.calls[0][0]; + expect(easeToArgs.bearing).toBe(0); + expect(easeToArgs.offset[0]).toBe(-0); + + map.setBearing(0); + simulate.keydown(map.getCanvasContainer(), { keyCode: 39, key: 'ArrowRight', shiftKey: true }); + expect(spy).toHaveBeenCalledTimes(2); + easeToArgs = spy.mock.calls[1][0]; + expect(easeToArgs.bearing).toBe(0); + expect(easeToArgs.offset[0]).toBe(-0); + }); + + test('KeyboardHandler pitches map in response to Shift+up/down arrow keys', async () => { + const map = createMap({ zoom: 10, center: [0, 0], pitch: 30 }); + const spy = jest.spyOn(map, 'easeTo'); + + simulate.keydown(map.getCanvasContainer(), { keyCode: 32, key: ' ' }); + expect(map.easeTo).not.toHaveBeenCalled(); + + simulate.keydown(map.getCanvasContainer(), { keyCode: 40, key: 'ArrowDown', shiftKey: true }); + expect(map.easeTo).toHaveBeenCalled(); + let easeToArgs = spy.mock.calls[0][0]; + expect(easeToArgs.pitch).toBe(20); + expect(easeToArgs.offset[1]).toBe(-0); + + map.setPitch(30); + simulate.keydown(map.getCanvasContainer(), { keyCode: 38, key: 'ArrowUp', shiftKey: true }); + expect(spy).toHaveBeenCalledTimes(2); + easeToArgs = spy.mock.calls[1][0]; + expect(easeToArgs.pitch).toBe(40); + expect(easeToArgs.offset[1]).toBe(-0); + }); + + test('KeyboardHandler does not pitch map in response to Shift+up/down arrow keys when disableRotation has been called', async () => { + const map = createMap({ zoom: 10, center: [0, 0], pitch: 30 }); + const spy = jest.spyOn(map, 'easeTo'); + map.keyboard.disableRotation(); + + simulate.keydown(map.getCanvasContainer(), { keyCode: 32, key: ' ' }); + expect(map.easeTo).not.toHaveBeenCalled(); + + simulate.keydown(map.getCanvasContainer(), { keyCode: 40, key: 'ArrowDown', shiftKey: true }); + expect(map.easeTo).toHaveBeenCalled(); + let easeToArgs = spy.mock.calls[0][0]; + expect(easeToArgs.pitch).toBe(30); + expect(easeToArgs.offset[1]).toBe(-0); + + map.setPitch(30); + simulate.keydown(map.getCanvasContainer(), { keyCode: 38, key: 'ArrowUp', shiftKey: true }); + expect(spy).toHaveBeenCalledTimes(2); + easeToArgs = spy.mock.calls[1][0]; + expect(easeToArgs.pitch).toBe(30); + expect(easeToArgs.offset[1]).toBe(-0); + }); + + test('KeyboardHandler zooms map in response to -/+ keys', () => { + const map = createMap({ zoom: 10, center: [0, 0] }); + const spy = jest.spyOn(map, 'easeTo'); + + simulate.keydown(map.getCanvasContainer(), { keyCode: 187, key: 'Equal' }); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy.mock.calls[0][0].zoom).toBe(11); + + map.setZoom(10); + simulate.keydown(map.getCanvasContainer(), { keyCode: 187, key: 'Equal', shiftKey: true }); + expect(spy).toHaveBeenCalledTimes(2); + expect(spy.mock.calls[1][0].zoom).toBe(12); + + map.setZoom(10); + simulate.keydown(map.getCanvasContainer(), { keyCode: 189, key: 'Minus' }); + expect(spy).toHaveBeenCalledTimes(3); + expect(spy.mock.calls[2][0].zoom).toBe(9); + + map.setZoom(10); + simulate.keydown(map.getCanvasContainer(), { keyCode: 189, key: 'Minus', shiftKey: true }); + expect(spy).toHaveBeenCalledTimes(4); + expect(spy.mock.calls[3][0].zoom).toBe(8); + }); + + test('KeyboardHandler zooms map in response to -/+ keys when disableRotation has been called', () => { + const map = createMap({ zoom: 10, center: [0, 0] }); + const spy = jest.spyOn(map, 'easeTo'); + map.keyboard.disableRotation(); + + simulate.keydown(map.getCanvasContainer(), { keyCode: 187, key: 'Equal' }); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy.mock.calls[0][0].zoom).toBe(11); + + map.setZoom(10); + simulate.keydown(map.getCanvasContainer(), { keyCode: 187, key: 'Equal', shiftKey: true }); + expect(spy).toHaveBeenCalledTimes(2); + expect(spy.mock.calls[1][0].zoom).toBe(12); + + map.setZoom(10); + simulate.keydown(map.getCanvasContainer(), { keyCode: 189, key: 'Minus' }); + expect(spy).toHaveBeenCalledTimes(3); + expect(spy.mock.calls[2][0].zoom).toBe(9); + + map.setZoom(10); + simulate.keydown(map.getCanvasContainer(), { keyCode: 189, key: 'Minus', shiftKey: true }); + expect(spy).toHaveBeenCalledTimes(4); + expect(spy.mock.calls[3][0].zoom).toBe(8); + }); +}); diff --git a/packages/map/__tests__/handler/map_event.spec.ts b/packages/map/__tests__/handler/map_event.spec.ts new file mode 100644 index 00000000000..6404bac1ed7 --- /dev/null +++ b/packages/map/__tests__/handler/map_event.spec.ts @@ -0,0 +1,182 @@ +import type { MapOptions } from '../../src/map/map'; +import { Map } from '../../src/map/map'; +import { DOM } from '../../src/map/util/dom'; +import simulate from '../libs/simulate_interaction'; +import { beforeMapTest } from '../libs/util'; + +function createMap() { + return new Map({ + interactive: true, + container: DOM.create('div', '', window.document.body), + } as any as MapOptions); +} + +beforeEach(() => { + beforeMapTest(); +}); + +describe('map events', () => { + test('MapEvent handler fires touch events with correct values', () => { + const map = createMap(); + const target = map.getCanvasContainer(); + + const touchstart = jest.fn(); + const touchmove = jest.fn(); + const touchend = jest.fn(); + + map.on('touchstart', touchstart); + map.on('touchmove', touchmove); + map.on('touchend', touchend); + + const touchesStart = [{ target, identifier: 1, clientX: 0, clientY: 50 }]; + const touchesMove = [{ target, identifier: 1, clientX: 0, clientY: 60 }]; + const touchesEnd = [{ target, identifier: 1, clientX: 0, clientY: 60 }]; + + simulate.touchstart(map.getCanvasContainer(), { + touches: touchesStart, + targetTouches: touchesStart, + }); + expect(touchstart).toHaveBeenCalledTimes(1); + expect(touchstart.mock.calls[0][0].point).toEqual({ x: 0, y: 50 }); + expect(touchmove).toHaveBeenCalledTimes(0); + expect(touchend).toHaveBeenCalledTimes(0); + + simulate.touchmove(map.getCanvasContainer(), { + touches: touchesMove, + targetTouches: touchesMove, + }); + expect(touchstart).toHaveBeenCalledTimes(1); + expect(touchmove).toHaveBeenCalledTimes(1); + expect(touchmove.mock.calls[0][0].point).toEqual({ x: 0, y: 60 }); + expect(touchend).toHaveBeenCalledTimes(0); + + simulate.touchend(map.getCanvasContainer(), { + touches: [], + targetTouches: [], + changedTouches: touchesEnd, + }); + expect(touchstart).toHaveBeenCalledTimes(1); + expect(touchmove).toHaveBeenCalledTimes(1); + expect(touchend).toHaveBeenCalledTimes(1); + expect(touchend.mock.calls[0][0].point).toEqual({ x: 0, y: 60 }); + + map.remove(); + }); + + test('MapEvent handler fires touchmove even while drag handler is active', () => { + const map = createMap(); + const target = map.getCanvasContainer(); + map.dragPan.enable(); + + const touchstart = jest.fn(); + const touchmove = jest.fn(); + const touchend = jest.fn(); + const drag = jest.fn(); + + map.on('touchstart', touchstart); + map.on('touchmove', touchmove); + map.on('touchend', touchend); + map.on('drag', drag); + + const touchesStart = [{ target, identifier: 1, clientX: 0, clientY: 50 }]; + const touchesMove = [{ target, identifier: 1, clientX: 0, clientY: 60 }]; + const touchesEnd = [{ target, identifier: 1, clientX: 0, clientY: 60 }]; + + simulate.touchstart(map.getCanvasContainer(), { + touches: touchesStart, + targetTouches: touchesStart, + }); + expect(touchstart).toHaveBeenCalledTimes(1); + expect(touchstart.mock.calls[0][0].point).toEqual({ x: 0, y: 50 }); + expect(touchmove).toHaveBeenCalledTimes(0); + expect(touchend).toHaveBeenCalledTimes(0); + + simulate.touchmove(map.getCanvasContainer(), { + touches: touchesMove, + targetTouches: touchesMove, + }); + expect(touchstart).toHaveBeenCalledTimes(1); + expect(touchmove).toHaveBeenCalledTimes(1); + expect(touchmove.mock.calls[0][0].point).toEqual({ x: 0, y: 60 }); + expect(touchend).toHaveBeenCalledTimes(0); + + simulate.touchend(map.getCanvasContainer(), { + touches: [], + targetTouches: [], + changedTouches: touchesEnd, + }); + expect(touchstart).toHaveBeenCalledTimes(1); + expect(touchmove).toHaveBeenCalledTimes(1); + expect(touchend).toHaveBeenCalledTimes(1); + expect(touchend.mock.calls[0][0].point).toEqual({ x: 0, y: 60 }); + + map._renderTaskQueue.run(); + expect(drag).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test('MapEvent handler fires contextmenu on MacOS/Linux, but only at mouseup', () => { + const map = createMap(); + const target = map.getCanvasContainer(); + map.dragPan.enable(); + + const contextmenu = jest.fn(); + + map.on('contextmenu', contextmenu); + + simulate.mousedown(map.getCanvasContainer(), { target, button: 2, clientX: 10, clientY: 10 }); + simulate.contextmenu(map.getCanvasContainer(), { target }); // triggered immediately after mousedown + expect(contextmenu).toHaveBeenCalledTimes(0); + simulate.mouseup(map.getCanvasContainer(), { target, button: 2, clientX: 10, clientY: 10 }); + expect(contextmenu).toHaveBeenCalledTimes(1); + }); + + test('MapEvent handler does not fire contextmenu on MacOS/Linux, when moved', () => { + const map = createMap(); + const target = map.getCanvasContainer(); + map.dragPan.enable(); + + const contextmenu = jest.fn(); + + map.on('contextmenu', contextmenu); + + simulate.mousedown(map.getCanvasContainer(), { target, button: 2, clientX: 10, clientY: 10 }); + simulate.contextmenu(map.getCanvasContainer(), { target }); // triggered immediately after mousedown + simulate.mousemove(map.getCanvasContainer(), { target, buttons: 2, clientX: 50, clientY: 10 }); + simulate.mouseup(map.getCanvasContainer(), { target, button: 2, clientX: 70, clientY: 10 }); + expect(contextmenu).toHaveBeenCalledTimes(0); + }); + + test('MapEvent handler fires contextmenu on Windows', () => { + const map = createMap(); + const target = map.getCanvasContainer(); + map.dragPan.enable(); + + const contextmenu = jest.fn(); + + map.on('contextmenu', contextmenu); + + simulate.mousedown(map.getCanvasContainer(), { target, button: 2, clientX: 10, clientY: 10 }); + simulate.mouseup(map.getCanvasContainer(), { target, button: 2, clientX: 10, clientY: 10 }); + expect(contextmenu).toHaveBeenCalledTimes(0); + simulate.contextmenu(map.getCanvasContainer(), { target, button: 2, clientX: 10, clientY: 10 }); // triggered only after mouseup + expect(contextmenu).toHaveBeenCalledTimes(1); + }); + + test('MapEvent handler does not fire contextmenu on Windows, when moved', () => { + const map = createMap(); + const target = map.getCanvasContainer(); + map.dragPan.enable(); + + const contextmenu = jest.fn(); + + map.on('contextmenu', contextmenu); + + simulate.mousedown(map.getCanvasContainer(), { target, button: 2, clientX: 10, clientY: 10 }); + simulate.mousemove(map.getCanvasContainer(), { target, buttons: 2, clientX: 50, clientY: 10 }); + simulate.mouseup(map.getCanvasContainer(), { target, button: 2, clientX: 50, clientY: 10 }); + simulate.contextmenu(map.getCanvasContainer(), { target, button: 2, clientX: 10, clientY: 10 }); // triggered only after mouseup + expect(contextmenu).toHaveBeenCalledTimes(0); + }); +}); diff --git a/packages/map/__tests__/handler/mouse_handler_interface.spec.ts b/packages/map/__tests__/handler/mouse_handler_interface.spec.ts new file mode 100644 index 00000000000..7b1673d7b25 --- /dev/null +++ b/packages/map/__tests__/handler/mouse_handler_interface.spec.ts @@ -0,0 +1,117 @@ +import Point from '@mapbox/point-geometry'; + +import { + generateMousePanHandler, + generateMousePitchHandler, + generateMouseRotationHandler, +} from '../../src/map/handler/mouse'; + +describe('mouse handler tests', () => { + test('MouseRotateHandler', () => { + const mouseRotate = generateMouseRotationHandler({ clickTolerance: 2 }); + + expect(mouseRotate.isActive()).toBe(false); + expect(mouseRotate.isEnabled()).toBe(false); + mouseRotate.enable(); + expect(mouseRotate.isEnabled()).toBe(true); + + mouseRotate.dragStart(new MouseEvent('mousedown', { buttons: 2, button: 2 }), new Point(0, 0)); + expect(mouseRotate.isActive()).toBe(false); + + const underToleranceMove = new MouseEvent('mousemove', { buttons: 2, clientX: 1, clientY: 1 }); + expect(mouseRotate.dragMove(underToleranceMove, new Point(1, 1))).toBeUndefined(); + expect(mouseRotate.isActive()).toBe(false); + + const overToleranceMove = new MouseEvent('mousemove', { buttons: 2, clientX: 10, clientY: 10 }); + expect(mouseRotate.dragMove(overToleranceMove, new Point(10, 10))).toEqual({ bearingDelta: 8 }); + expect(mouseRotate.isActive()).toBe(true); + + mouseRotate.dragEnd(new MouseEvent('mouseup', { buttons: 0, button: 2 })); + expect(mouseRotate.isActive()).toBe(false); + + mouseRotate.disable(); + expect(mouseRotate.isEnabled()).toBe(false); + + mouseRotate.dragStart(new MouseEvent('mousedown', { buttons: 2, button: 2 }), new Point(0, 0)); + expect(mouseRotate.isActive()).toBe(false); + + expect(mouseRotate.dragMove(underToleranceMove, new Point(1, 1))).toBeUndefined(); + expect(mouseRotate.isActive()).toBe(false); + + expect(mouseRotate.dragMove(overToleranceMove, new Point(10, 10))).toBeUndefined(); + expect(mouseRotate.isActive()).toBe(false); + }); + + test('MousePitchHandler', () => { + const mousePitch = generateMousePitchHandler({ clickTolerance: 2 }); + + expect(mousePitch.isActive()).toBe(false); + expect(mousePitch.isEnabled()).toBe(false); + mousePitch.enable(); + expect(mousePitch.isEnabled()).toBe(true); + + mousePitch.dragStart(new MouseEvent('mousedown', { buttons: 2, button: 2 }), new Point(0, 0)); + expect(mousePitch.isActive()).toBe(false); + + const underToleranceMove = new MouseEvent('mousemove', { buttons: 2, clientX: 1, clientY: 1 }); + expect(mousePitch.dragMove(underToleranceMove, new Point(1, 1))).toBeUndefined(); + expect(mousePitch.isActive()).toBe(false); + + const overToleranceMove = new MouseEvent('mousemove', { buttons: 2, clientX: 10, clientY: 10 }); + expect(mousePitch.dragMove(overToleranceMove, new Point(10, 10))).toEqual({ pitchDelta: -5 }); + expect(mousePitch.isActive()).toBe(true); + + mousePitch.dragEnd(new MouseEvent('mouseup', { buttons: 0, button: 2 })); + expect(mousePitch.isActive()).toBe(false); + + mousePitch.disable(); + expect(mousePitch.isEnabled()).toBe(false); + + mousePitch.dragStart(new MouseEvent('mousedown', { buttons: 2, button: 2 }), new Point(0, 0)); + expect(mousePitch.isActive()).toBe(false); + + expect(mousePitch.dragMove(underToleranceMove, new Point(1, 1))).toBeUndefined(); + expect(mousePitch.isActive()).toBe(false); + + expect(mousePitch.dragMove(overToleranceMove, new Point(10, 10))).toBeUndefined(); + expect(mousePitch.isActive()).toBe(false); + }); + + test('MousePanHandler', () => { + const mousePan = generateMousePanHandler({ clickTolerance: 2 }); + + expect(mousePan.isActive()).toBe(false); + expect(mousePan.isEnabled()).toBe(false); + mousePan.enable(); + expect(mousePan.isEnabled()).toBe(true); + + mousePan.dragStart(new MouseEvent('mousedown', { buttons: 1, button: 0 }), new Point(0, 0)); + expect(mousePan.isActive()).toBe(true); + + const underToleranceMove = new MouseEvent('mousemove', { buttons: 1, clientX: 1, clientY: 1 }); + expect(mousePan.dragMove(underToleranceMove, new Point(1, 1))).toBeUndefined(); + expect(mousePan.isActive()).toBe(true); + + const overToleranceMove = new MouseEvent('mousemove', { buttons: 1, clientX: 10, clientY: 10 }); + expect(mousePan.dragMove(overToleranceMove, new Point(10, 10))).toEqual({ + around: { x: 10, y: 10 }, + panDelta: { x: 10, y: 10 }, + }); + expect(mousePan.isActive()).toBe(true); + + mousePan.dragEnd(new MouseEvent('mouseup', { buttons: 0, button: 0 })); + expect(mousePan.isActive()).toBe(false); + + mousePan.disable(); + expect(mousePan.isEnabled()).toBe(false); + + mousePan.dragStart(new MouseEvent('mousedown', { buttons: 2, button: 2 }), new Point(0, 0)); + expect(mousePan.isActive()).toBe(false); + + expect(mousePan.dragMove(underToleranceMove, new Point(1, 1))).toBeUndefined(); + expect(mousePan.isActive()).toBe(false); + + expect(mousePan.dragMove(overToleranceMove, new Point(10, 10))).toBeUndefined(); + expect(mousePan.isActive()).toBe(false); + }); +}); diff --git a/packages/map/__tests__/handler/mouse_rotate.spec.ts b/packages/map/__tests__/handler/mouse_rotate.spec.ts new file mode 100644 index 00000000000..ff7d642e9a6 --- /dev/null +++ b/packages/map/__tests__/handler/mouse_rotate.spec.ts @@ -0,0 +1,62 @@ +import { Map } from '../../src/map/map'; +import { browser } from '../../src/map/util/browser'; +import { DOM } from '../../src/map/util/dom'; +import { extend } from '../../src/map/util/util'; +import simulate from '../libs/simulate_interaction'; +import { beforeMapTest } from '../libs/util'; + +function createMap(options?) { + return new Map(extend({ container: DOM.create('div', '', window.document.body) }, options)); +} + +beforeEach(() => { + beforeMapTest(); +}); + +describe('mouse rotate', () => { + test('MouseRotateHandler#isActive', () => { + const map = createMap({ interactive: true }); + const mouseRotate = map.handlers._handlersById.mouseRotate; + + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockReturnValue(0); + expect(mouseRotate.isActive()).toBe(false); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2, clientX: 0, clientY: 0 }); + map._renderTaskQueue.run(); + expect(mouseRotate.isActive()).toBe(false); + + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + expect(mouseRotate.isActive()).toBe(true); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 2 }); + map._renderTaskQueue.run(); + expect(mouseRotate.isActive()).toBe(false); + + map.remove(); + }); + + test('MouseRotateHandler#isActive #4622 regression test', () => { + const map = createMap({ interactive: true }); + const mouseRotate = map.handlers._handlersById.mouseRotate; + + // Prevent inertial rotation. + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2 }); + map._renderTaskQueue.run(); + expect(mouseRotate.isActive()).toBe(false); + + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + expect(mouseRotate.isActive()).toBe(true); + + // Some browsers don't fire mouseup when it happens outside the window. + // Make the handler in active when it encounters a mousemove without the button pressed. + + simulate.mousemove(map.getCanvasContainer(), { buttons: 0, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + expect(mouseRotate.isActive()).toBe(false); + + map.remove(); + }); +}); diff --git a/packages/map/__tests__/handler/one_finger_touch_drag_handler_interface.spec.ts b/packages/map/__tests__/handler/one_finger_touch_drag_handler_interface.spec.ts new file mode 100644 index 00000000000..b6c0873097f --- /dev/null +++ b/packages/map/__tests__/handler/one_finger_touch_drag_handler_interface.spec.ts @@ -0,0 +1,96 @@ +import Point from '@mapbox/point-geometry'; + +import { + generateOneFingerTouchPitchHandler, + generateOneFingerTouchRotationHandler, +} from '../../src/map/handler/one_finger_touch_drag'; + +const testTouch = { identifier: 0 } as Touch; + +describe('one touch drag handler tests', () => { + test('OneFingerTouchRotateHandler', () => { + const oneTouchRotate = generateOneFingerTouchRotationHandler({ clickTolerance: 2 }); + + expect(oneTouchRotate.isActive()).toBe(false); + expect(oneTouchRotate.isEnabled()).toBe(false); + oneTouchRotate.enable(); + expect(oneTouchRotate.isEnabled()).toBe(true); + + oneTouchRotate.dragStart( + new TouchEvent('touchstart', { targetTouches: [testTouch] }), + new Point(0, 0), + ); + expect(oneTouchRotate.isActive()).toBe(false); + + const underToleranceMove = new TouchEvent('touchmove', { targetTouches: [testTouch] }); + expect(oneTouchRotate.dragMove(underToleranceMove, new Point(1, 1))).toBeUndefined(); + expect(oneTouchRotate.isActive()).toBe(false); + + const overToleranceMove = new TouchEvent('touchmove', { targetTouches: [testTouch] }); + expect(oneTouchRotate.dragMove(overToleranceMove, new Point(10, 10))).toEqual({ + bearingDelta: 8, + }); + expect(oneTouchRotate.isActive()).toBe(true); + + oneTouchRotate.dragEnd(new TouchEvent('touchend', { targetTouches: [testTouch] })); + expect(oneTouchRotate.isActive()).toBe(false); + + oneTouchRotate.disable(); + expect(oneTouchRotate.isEnabled()).toBe(false); + + oneTouchRotate.dragStart( + new TouchEvent('touchstart', { targetTouches: [testTouch] }), + new Point(0, 0), + ); + expect(oneTouchRotate.isActive()).toBe(false); + + expect(oneTouchRotate.dragMove(underToleranceMove, new Point(1, 1))).toBeUndefined(); + expect(oneTouchRotate.isActive()).toBe(false); + + expect(oneTouchRotate.dragMove(overToleranceMove, new Point(10, 10))).toBeUndefined(); + expect(oneTouchRotate.isActive()).toBe(false); + }); + + test('OneFingerTouchPitchHandler', () => { + const oneTouchPitch = generateOneFingerTouchPitchHandler({ clickTolerance: 2 }); + + expect(oneTouchPitch.isActive()).toBe(false); + expect(oneTouchPitch.isEnabled()).toBe(false); + oneTouchPitch.enable(); + expect(oneTouchPitch.isEnabled()).toBe(true); + + oneTouchPitch.dragStart( + new TouchEvent('touchstart', { targetTouches: [testTouch] }), + new Point(0, 0), + ); + expect(oneTouchPitch.isActive()).toBe(false); + + const underToleranceMove = new TouchEvent('touchmove', { targetTouches: [testTouch] }); + expect(oneTouchPitch.dragMove(underToleranceMove, new Point(1, 1))).toBeUndefined(); + expect(oneTouchPitch.isActive()).toBe(false); + + const overToleranceMove = new TouchEvent('touchmove', { targetTouches: [testTouch] }); + expect(oneTouchPitch.dragMove(overToleranceMove, new Point(10, 10))).toEqual({ + pitchDelta: -5, + }); + expect(oneTouchPitch.isActive()).toBe(true); + + oneTouchPitch.dragEnd(new TouchEvent('touchend', { targetTouches: [testTouch] })); + expect(oneTouchPitch.isActive()).toBe(false); + + oneTouchPitch.disable(); + expect(oneTouchPitch.isEnabled()).toBe(false); + + oneTouchPitch.dragStart( + new TouchEvent('touchstart', { targetTouches: [testTouch] }), + new Point(0, 0), + ); + expect(oneTouchPitch.isActive()).toBe(false); + + expect(oneTouchPitch.dragMove(underToleranceMove, new Point(1, 1))).toBeUndefined(); + expect(oneTouchPitch.isActive()).toBe(false); + + expect(oneTouchPitch.dragMove(overToleranceMove, new Point(10, 10))).toBeUndefined(); + expect(oneTouchPitch.isActive()).toBe(false); + }); +}); diff --git a/packages/map/__tests__/handler/scroll_zoom.spec.ts b/packages/map/__tests__/handler/scroll_zoom.spec.ts index da5779af1d9..a488fa69ea7 100644 --- a/packages/map/__tests__/handler/scroll_zoom.spec.ts +++ b/packages/map/__tests__/handler/scroll_zoom.spec.ts @@ -1,82 +1,296 @@ -import Point from '../../src/geo/point'; -import type HandlerManager from '../../src/handler/handler_manager'; -import ScrollZoomHandler from '../../src/handler/scroll_zoom'; -import { Map } from '../../src/map'; - -describe('Map', () => { - const el = document.createElement('div'); - el.id = 'test-div-id'; - // el.style.width = '500px'; - // el.style.height = '500px'; - el.style.background = '#aaa'; - let map: Map; - let handlerManager: HandlerManager; - let scrollZoomHandler: ScrollZoomHandler; - document.querySelector('body')?.appendChild(el); - beforeEach(() => { - map = new Map({ - container: el, - zoom: 10, +import { Map } from '../../src/map/map'; +import { browser } from '../../src/map/util/browser'; +import { DOM } from '../../src/map/util/dom'; +import simulate from '../libs/simulate_interaction'; +import { beforeMapTest, setPerformance } from '../libs/util'; + +function createMap() { + return new Map({ + container: DOM.create('div', '', window.document.body), + }); +} + +beforeEach(() => { + beforeMapTest(); +}); + +describe('ScrollZoomHandler', () => { + test('Zooms for single mouse wheel tick', () => { + const browserNow = jest.spyOn(browser, 'now'); + let now = 1555555555555; + browserNow.mockReturnValue(now); + + const map = createMap(); + map._renderTaskQueue.run(); + + // simulate a single 'wheel' event + const startZoom = map.getZoom(); + + simulate.wheel(map.getCanvasContainer(), { + type: 'wheel', + deltaY: -simulate.magicWheelZoomDelta, }); - handlerManager = map.handlers; - // @ts-ignore - scrollZoomHandler = handlerManager.handlersById['scrollZoom']; + map._renderTaskQueue.run(); + + now += 400; + browserNow.mockReturnValue(now); + map._renderTaskQueue.run(); + + expect(map.getZoom() - startZoom).toBeCloseTo(0.0285, 3); + + map.remove(); }); - // handlerManager isactive - it('handlerManager is active', () => { - expect(handlerManager.isActive()).toEqual(false); + test('Zooms for single mouse wheel tick with non-magical deltaY', (done) => { + const browserNow = jest.spyOn(browser, 'now'); + const now = 1555555555555; + browserNow.mockReturnValue(now); + + const map = createMap(); + map._renderTaskQueue.run(); + + // Simulate a single 'wheel' event without the magical deltaY value. + // This requires the handler to briefly wait to see if a subsequent + // event is coming in order to guess trackpad vs. mouse wheel + simulate.wheel(map.getCanvasContainer(), { type: 'wheel', deltaY: -20 }); + map.on('zoomstart', () => { + map.remove(); + done(); + }); }); - it('scrollZoomHandler', () => { - expect(scrollZoomHandler).toBeInstanceOf(ScrollZoomHandler); + test('Zooms for multiple mouse wheel ticks', () => { + const browserNow = jest.spyOn(browser, 'now'); + let now = 1555555555555; + browserNow.mockReturnValue(now); + + const map = createMap(); + + map._renderTaskQueue.run(); + const startZoom = map.getZoom(); + + const events = [ + [2, { type: 'wheel', deltaY: -simulate.magicWheelZoomDelta }], + [7, { type: 'wheel', deltaY: -41 }], + [30, { type: 'wheel', deltaY: -169 }], + [1, { type: 'wheel', deltaY: -801 }], + [5, { type: 'wheel', deltaY: -326 }], + [20, { type: 'wheel', deltaY: -345 }], + [22, { type: 'wheel', deltaY: -376 }], + ] as [number, any][]; + + const end = now + 500; + let lastWheelEvent = now; + + // simulate the above sequence of wheel events, with render frames + // interspersed every 20ms + while (now < end) { + now += 1; + browserNow.mockReturnValue(now); + if (events.length && lastWheelEvent + events[0][0] === now) { + const [, event] = events.shift(); + simulate.wheel(map.getCanvasContainer(), event); + lastWheelEvent = now; + } + if (now % 20 === 0) { + map._renderTaskQueue.run(); + } + } + + expect(map.getZoom() - startZoom).toBeCloseTo(1.944, 3); + + map.remove(); + }); + + test('Gracefully ignores wheel events with deltaY: 0', () => { + const browserNow = jest.spyOn(browser, 'now'); + let now = 1555555555555; + browserNow.mockReturnValue(now); + + const map = createMap(); + map._renderTaskQueue.run(); + + const startZoom = map.getZoom(); + // simulate shift+'wheel' events + simulate.wheel(map.getCanvasContainer(), { type: 'wheel', deltaY: -0, shiftKey: true }); + simulate.wheel(map.getCanvasContainer(), { type: 'wheel', deltaY: -0, shiftKey: true }); + simulate.wheel(map.getCanvasContainer(), { type: 'wheel', deltaY: -0, shiftKey: true }); + simulate.wheel(map.getCanvasContainer(), { type: 'wheel', deltaY: -0, shiftKey: true }); + map._renderTaskQueue.run(); + + now += 400; + browserNow.mockReturnValue(now); + map._renderTaskQueue.run(); + + expect(map.getZoom() - startZoom).toBe(0.0); }); - it('boxZoomHandler box select', () => { - // @ts-ignore - const boxZoom = handlerManager.handlersById['boxZoom']; - boxZoom.disable(); - boxZoom.enable(); - - // 模拟鼠标按下事件 - let e = new MouseEvent('mousedown', { - shiftKey: true, - button: 0, - clientX: 100, - clientY: 100, + + test('Gracefully handle wheel events that cancel each other out before the first scroll frame', () => { + // See also https://github.com/mapbox/mapbox-gl-js/issues/6782 + const browserNow = jest.spyOn(browser, 'now'); + let now = 1555555555555; + browserNow.mockReturnValue(now); + + const map = createMap(); + map._renderTaskQueue.run(); + + simulate.wheel(map.getCanvasContainer(), { type: 'wheel', deltaY: -1 }); + simulate.wheel(map.getCanvasContainer(), { type: 'wheel', deltaY: -1 }); + now += 1; + browserNow.mockReturnValue(now); + simulate.wheel(map.getCanvasContainer(), { type: 'wheel', deltaY: 2 }); + + map._renderTaskQueue.run(); + + now += 400; + browserNow.mockReturnValue(now); + map._renderTaskQueue.run(); + }); + + test('does not zoom if preventDefault is called on the wheel event', () => { + const browserNow = jest.spyOn(browser, 'now'); + let now = 1555555555555; + browserNow.mockReturnValue(now); + + const map = createMap(); + + map.on('wheel', (e) => e.preventDefault()); + + simulate.wheel(map.getCanvasContainer(), { + type: 'wheel', + deltaY: -simulate.magicWheelZoomDelta, + }); + map._renderTaskQueue.run(); + + now += 400; + browserNow.mockReturnValue(now); + map._renderTaskQueue.run(); + + expect(map.getZoom()).toBe(0); + + map.remove(); + }); + + test('emits one movestart event and one moveend event while zooming', () => { + const browserNow = jest.spyOn(browser, 'now'); + let now = 1555555555555; + browserNow.mockReturnValue(now); + jest.useFakeTimers(); + setPerformance(); + const map = createMap(); + + let startCount = 0; + map.on('movestart', () => { + startCount += 1; }); - // 创建一个 Point 对象 - const point1 = new Point(0, 0); - //@ts-ignore - boxZoom.mousedown(e, point1); - - // 模拟鼠标移动事件 - const point2 = new Point(200, 200); - e = new MouseEvent('mousemove', { clientX: 200, clientY: 200 }); - //@ts-ignore - boxZoom.mousemoveWindow(e, point2); - - // 模拟鼠标释放事件 - const point3 = new Point(200, 200); - e = new MouseEvent('mouseup', { clientX: 200, clientY: 200 }); - //@ts-ignore - boxZoom.mouseupWindow(e, point3); - expect(map.getZoom()).toEqual(10); - - // 验证结果 - // 这将取决于你的boxZoomHandler如何处理这些事件 - // 例如,你可能会检查地图的缩放级别或视口是否已经改变 + + let endCount = 0; + map.on('moveend', () => { + endCount += 1; + }); + + const events = [ + [2, { type: 'trackpad', deltaY: -1 }], + [7, { type: 'trackpad', deltaY: -2 }], + [30, { type: 'wheel', deltaY: -5 }], + ] as [number, any][]; + + const end = now + 50; + let lastWheelEvent = now; + + while (now < end) { + now += 1; + browserNow.mockReturnValue(now); + if (events.length && lastWheelEvent + events[0][0] === now) { + const [, event] = events.shift(); + simulate.wheel(map.getCanvasContainer(), event); + lastWheelEvent = now; + } + if (now % 20 === 0) { + map._renderTaskQueue.run(); + } + } + + jest.advanceTimersByTime(200); + + map._renderTaskQueue.run(); + + expect(startCount).toBe(1); + expect(endCount).toBe(1); }); - // wheel - it('scrollZoomHandler wheel', () => { - const e = new WheelEvent('wheel', { deltaY: -500 }); - scrollZoomHandler.wheel(e); - scrollZoomHandler.renderFrame(); - expect(map.getZoom()).toEqual(10); + + test('emits one zoomstart event and one zoomend event while zooming', () => { + const browserNow = jest.spyOn(browser, 'now'); + let now = 1555555555555; + browserNow.mockReturnValue(now); + + jest.useFakeTimers(); + setPerformance(); + const map = createMap(); + + let startCount = 0; + map.on('zoomstart', () => { + startCount += 1; + }); + + let endCount = 0; + map.on('zoomend', () => { + endCount += 1; + }); + + const events = [ + [2, { type: 'trackpad', deltaY: -1 }], + [7, { type: 'trackpad', deltaY: -2 }], + [30, { type: 'wheel', deltaY: -5 }], + ] as [number, any][]; + + const end = now + 50; + let lastWheelEvent = now; + + while (now < end) { + now += 1; + browserNow.mockReturnValue(now); + if (events.length && lastWheelEvent + events[0][0] === now) { + const [, event] = events.shift(); + simulate.wheel(map.getCanvasContainer(), event); + lastWheelEvent = now; + } + if (now % 20 === 0) { + map._renderTaskQueue.run(); + } + } + + jest.advanceTimersByTime(200); + map._renderTaskQueue.run(); + + expect(startCount).toBe(1); + expect(endCount).toBe(1); }); - // disable - it('scrollZoomHandler disable', () => { - scrollZoomHandler.disable(); - expect(scrollZoomHandler.isEnabled()).toEqual(false); + test('Zooms for single mouse wheel tick while not in the center of the map and terrain is on, should zoom according to mouse position', () => { + const browserNow = jest.spyOn(browser, 'now'); + let now = 1555555555555; + browserNow.mockReturnValue(now); + + const map = createMap(); + map._renderTaskQueue.run(); + + // simulate a single 'wheel' event + simulate.wheel(map.getCanvasContainer(), { + type: 'wheel', + deltaY: -simulate.magicWheelZoomDelta, + clientX: 1000, + clientY: 1000, + }); + map._renderTaskQueue.run(); + + now += 400; + browserNow.mockReturnValue(now); + map._renderTaskQueue.run(); + + expect(map.getCenter().lat).toBeCloseTo(-11.6371, 3); + expect(map.getCenter().lng).toBeCloseTo(11.0286, 3); + + map.remove(); }); }); diff --git a/packages/map/__tests__/handler/tap_drag_zoom.spec.ts b/packages/map/__tests__/handler/tap_drag_zoom.spec.ts new file mode 100644 index 00000000000..63ad3dd8f53 --- /dev/null +++ b/packages/map/__tests__/handler/tap_drag_zoom.spec.ts @@ -0,0 +1,113 @@ +import type { MapOptions } from '../../src/map/map'; +import { Map } from '../../src/map/map'; +import simulate from '../libs/simulate_interaction'; +import { beforeMapTest } from '../libs/util'; + +function createMap() { + return new Map({ container: window.document.createElement('div') } as any as MapOptions); +} + +function setupEvents(map: Map) { + const zoomstart = jest.fn(); + map.on('zoomstart', zoomstart); + + const zoom = jest.fn(); + map.on('zoom', zoom); + + const zoomend = jest.fn(); + map.on('zoomend', zoomend); + + return { + zoomstart, + zoom, + zoomend, + }; +} + +beforeEach(() => { + beforeMapTest(); +}); + +describe('tap_drag_zoom', () => { + test('TapDragZoomHandler fires zoomstart, zoom, and zoomend at appropriate times in response to a double-tap and drag gesture', () => { + const map = createMap(); + const target = map.getCanvasContainer(); + + const { zoomstart, zoom, zoomend } = setupEvents(map); + + const pointTouchOptions = { + touches: [{ target, clientX: 100, clientY: 100 }], + }; + + simulate.touchstart(target, pointTouchOptions); + simulate.touchend(target); + simulate.touchstart(target, pointTouchOptions); + map._renderTaskQueue.run(); + + expect(zoomstart).not.toHaveBeenCalled(); + expect(zoom).not.toHaveBeenCalled(); + expect(zoomend).not.toHaveBeenCalled(); + + simulate.touchmove(target, { + touches: [{ target, clientX: 100, clientY: 110 }], + }); + map._renderTaskQueue.run(); + + expect(zoomstart).toHaveBeenCalled(); + expect(zoom).toHaveBeenCalled(); + expect(zoomend).not.toHaveBeenCalled(); + + simulate.touchend(target); + map._renderTaskQueue.run(); + expect(zoomend).toHaveBeenCalled(); + }); + + test('TapDragZoomHandler does not fire zoom on tap and drag if touchstart events are > 500ms apart', (done) => { + const map = createMap(); + const target = map.getCanvasContainer(); + + const { zoomstart, zoom, zoomend } = setupEvents(map); + + const pointTouchOptions = { + touches: [{ target, clientX: 100, clientY: 100 }], + }; + + simulate.touchstart(target, pointTouchOptions); + simulate.touchend(target); + setTimeout(() => { + simulate.touchstart(target, pointTouchOptions); + simulate.touchmove(target, { + touches: [{ target, clientX: 100, clientY: 110 }], + }); + map._renderTaskQueue.run(); + + expect(zoomstart).not.toHaveBeenCalled(); + expect(zoom).not.toHaveBeenCalled(); + expect(zoomend).not.toHaveBeenCalled(); + done(); + }, 510); + }); + + test('TapDragZoomHandler does not zoom on double-tap and drag if touchstart events are in different locations (>30px apart)', () => { + const map = createMap(); + const target = map.getCanvasContainer(); + + const { zoomstart, zoom, zoomend } = setupEvents(map); + + simulate.touchstart(target, { + touches: [{ target, clientX: 100, clientY: 100 }], + }); + simulate.touchend(target); + simulate.touchstart(target, { + touches: [{ target, clientX: 140, clientY: 100 }], + }); + simulate.touchmove(target, { + touches: [{ target, clientX: 140, clientY: 110 }], + }); + map._renderTaskQueue.run(); + + expect(zoomstart).not.toHaveBeenCalled(); + expect(zoom).not.toHaveBeenCalled(); + expect(zoomend).not.toHaveBeenCalled(); + }); +}); diff --git a/packages/map/__tests__/handler/two_fingers_touch.spec.ts b/packages/map/__tests__/handler/two_fingers_touch.spec.ts new file mode 100644 index 00000000000..d50413b9cbc --- /dev/null +++ b/packages/map/__tests__/handler/two_fingers_touch.spec.ts @@ -0,0 +1,230 @@ +import type { MapOptions } from '../../src/map/map'; +import { Map } from '../../src/map/map'; +import { DOM } from '../../src/map/util/dom'; +import simulate from '../libs/simulate_interaction'; +import { beforeMapTest } from '../libs/util'; + +function createMap() { + return new Map({ container: DOM.create('div', '', window.document.body) } as any as MapOptions); +} + +beforeEach(() => { + beforeMapTest(); +}); + +describe('touch zoom rotate', () => { + test('TwoFingersTouchZoomRotateHandler fires zoomstart, zoom, and zoomend events at appropriate times in response to a pinch-zoom gesture', () => { + const map = createMap(); + const target = map.getCanvasContainer(); + + const zoomstart = jest.fn(); + const zoom = jest.fn(); + const zoomend = jest.fn(); + + map.handlers._handlersById.tapZoom.disable(); + map.touchPitch.disable(); + map.on('zoomstart', zoomstart); + map.on('zoom', zoom); + map.on('zoomend', zoomend); + + simulate.touchstart(map.getCanvasContainer(), { + touches: [ + { target, identifier: 1, clientX: 0, clientY: -50 }, + { target, identifier: 2, clientX: 0, clientY: 50 }, + ], + }); + map._renderTaskQueue.run(); + expect(zoomstart).toHaveBeenCalledTimes(0); + expect(zoom).toHaveBeenCalledTimes(0); + expect(zoomend).toHaveBeenCalledTimes(0); + + simulate.touchmove(map.getCanvasContainer(), { + touches: [ + { target, identifier: 1, clientX: 0, clientY: -100 }, + { target, identifier: 2, clientX: 0, clientY: 100 }, + ], + }); + map._renderTaskQueue.run(); + expect(zoomstart).toHaveBeenCalledTimes(1); + expect(zoom).toHaveBeenCalledTimes(1); + expect(zoomend).toHaveBeenCalledTimes(0); + + simulate.touchmove(map.getCanvasContainer(), { + touches: [ + { target, identifier: 1, clientX: 0, clientY: -60 }, + { target, identifier: 2, clientX: 0, clientY: 60 }, + ], + }); + map._renderTaskQueue.run(); + expect(zoomstart).toHaveBeenCalledTimes(1); + expect(zoom).toHaveBeenCalledTimes(2); + expect(zoomend).toHaveBeenCalledTimes(0); + + simulate.touchend(map.getCanvasContainer(), { touches: [] }); + map._renderTaskQueue.run(); + + // incremented because inertia starts a second zoom + expect(zoomstart).toHaveBeenCalledTimes(2); + map._renderTaskQueue.run(); + expect(zoom).toHaveBeenCalledTimes(3); + expect(zoomend).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test('TwoFingersTouchZoomRotateHandler fires rotatestart, rotate, and rotateend events at appropriate times in response to a pinch-rotate gesture', () => { + const map = createMap(); + const target = map.getCanvasContainer(); + + const rotatestart = jest.fn(); + const rotate = jest.fn(); + const rotateend = jest.fn(); + + map.on('rotatestart', rotatestart); + map.on('rotate', rotate); + map.on('rotateend', rotateend); + + simulate.touchstart(map.getCanvasContainer(), { + touches: [ + { target, identifier: 0, clientX: 0, clientY: -50 }, + { target, identifier: 1, clientX: 0, clientY: 50 }, + ], + }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(0); + expect(rotate).toHaveBeenCalledTimes(0); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.touchmove(map.getCanvasContainer(), { + touches: [ + { target, identifier: 0, clientX: -50, clientY: 0 }, + { target, identifier: 1, clientX: 50, clientY: 0 }, + ], + }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(1); + expect(rotate).toHaveBeenCalledTimes(1); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.touchmove(map.getCanvasContainer(), { + touches: [ + { target, identifier: 0, clientX: 0, clientY: -50 }, + { target, identifier: 1, clientX: 0, clientY: 50 }, + ], + }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(1); + expect(rotate).toHaveBeenCalledTimes(2); + expect(rotateend).toHaveBeenCalledTimes(0); + + simulate.touchend(map.getCanvasContainer(), { touches: [] }); + map._renderTaskQueue.run(); + expect(rotatestart).toHaveBeenCalledTimes(1); + expect(rotate).toHaveBeenCalledTimes(2); + expect(rotateend).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test('TwoFingersTouchZoomRotateHandler does not begin a gesture if preventDefault is called on the touchstart event', () => { + const map = createMap(); + const target = map.getCanvasContainer(); + + map.on('touchstart', (e) => e.preventDefault()); + + const move = jest.fn(); + map.on('move', move); + + simulate.touchstart(map.getCanvasContainer(), { + touches: [ + { target, clientX: 0, clientY: 0 }, + { target, clientX: 5, clientY: 0 }, + ], + }); + map._renderTaskQueue.run(); + + simulate.touchmove(map.getCanvasContainer(), { + touches: [ + { target, clientX: 0, clientY: 0 }, + { target, clientX: 0, clientY: 5 }, + ], + }); + map._renderTaskQueue.run(); + + simulate.touchend(map.getCanvasContainer(), { touches: [] }); + map._renderTaskQueue.run(); + + expect(move).toHaveBeenCalledTimes(0); + + map.remove(); + }); + + test('TwoFingersTouchZoomRotateHandler starts zoom immediately when rotation disabled', () => { + const map = createMap(); + const target = map.getCanvasContainer(); + map.touchZoomRotate.disableRotation(); + map.handlers._handlersById.tapZoom.disable(); + + const zoomstart = jest.fn(); + const zoom = jest.fn(); + const zoomend = jest.fn(); + + map.on('zoomstart', zoomstart); + map.on('zoom', zoom); + map.on('zoomend', zoomend); + + simulate.touchstart(map.getCanvasContainer(), { + touches: [ + { target, identifier: 0, clientX: 0, clientY: -5 }, + { target, identifier: 2, clientX: 0, clientY: 5 }, + ], + }); + map._renderTaskQueue.run(); + expect(zoomstart).toHaveBeenCalledTimes(0); + expect(zoom).toHaveBeenCalledTimes(0); + expect(zoomend).toHaveBeenCalledTimes(0); + + simulate.touchmove(map.getCanvasContainer(), { + touches: [ + { target, identifier: 0, clientX: 0, clientY: -5 }, + { target, identifier: 2, clientX: 0, clientY: 6 }, + ], + }); + map._renderTaskQueue.run(); + expect(zoomstart).toHaveBeenCalledTimes(1); + expect(zoom).toHaveBeenCalledTimes(1); + expect(zoomend).toHaveBeenCalledTimes(0); + + simulate.touchmove(map.getCanvasContainer(), { + touches: [ + { target, identifier: 0, clientX: 0, clientY: -5 }, + { target, identifier: 2, clientX: 0, clientY: 4 }, + ], + }); + map._renderTaskQueue.run(); + expect(zoomstart).toHaveBeenCalledTimes(1); + expect(zoom).toHaveBeenCalledTimes(2); + expect(zoomend).toHaveBeenCalledTimes(0); + + simulate.touchend(map.getCanvasContainer(), { touches: [] }); + map._renderTaskQueue.run(); + // incremented because inertia starts a second zoom + expect(zoomstart).toHaveBeenCalledTimes(2); + map._renderTaskQueue.run(); + expect(zoom).toHaveBeenCalledTimes(3); + expect(zoomend).toHaveBeenCalledTimes(1); + + map.remove(); + }); + + test('TwoFingersTouchZoomRotateHandler adds css class used for disabling default touch behavior in some browsers', () => { + const map = createMap(); + + const className = 'l7-touch-zoom-rotate'; + expect(map.getCanvasContainer().classList.contains(className)).toBeTruthy(); + map.touchZoomRotate.disable(); + expect(map.getCanvasContainer().classList.contains(className)).toBeFalsy(); + map.touchZoomRotate.enable(); + expect(map.getCanvasContainer().classList.contains(className)).toBeTruthy(); + }); +}); diff --git a/packages/map/__tests__/hash.spec.ts b/packages/map/__tests__/hash.spec.ts deleted file mode 100644 index 8ccbf01cee0..00000000000 --- a/packages/map/__tests__/hash.spec.ts +++ /dev/null @@ -1,38 +0,0 @@ -import Hash from '../src/hash'; -import { Map } from '../src/map'; -describe('Map', () => { - const el = document.createElement('div'); - el.id = 'test-div-id'; - // el.style.width = '500px'; - // el.style.height = '500px'; - el.style.background = '#aaa'; - let map: Map; - let hash: Hash; - document.querySelector('body')?.appendChild(el); - beforeEach(() => { - map = new Map({ - container: el, - }); - hash = new Hash('map'); - hash.addTo(map); - }); - it('hash update', () => { - map.setZoom(10); - map.setBearing(10); - map.setPitch(10); - map.setCenter([0, 0]); - expect(window.location.hash).toEqual('#map=10/0/0'); - }); - - it('hash remove', () => { - hash.remove(); - // @ts-ignore - expect(hash.map).toEqual(undefined); - }); - it('hash onHashChange', () => { - window.location.hash = '#map=11/10/10'; - hash.onHashChange(); - expect(map.getZoom()).toEqual(11); - expect(map.getCenter()).toEqual({ lng: 10, lat: 10 }); - }); -}); diff --git a/packages/map/__tests__/libs/fixed.ts b/packages/map/__tests__/libs/fixed.ts new file mode 100644 index 00000000000..e2e384d469b --- /dev/null +++ b/packages/map/__tests__/libs/fixed.ts @@ -0,0 +1,25 @@ +export function fixedNum(n: number, precision = 10) { + const fixedNum = parseFloat(n.toFixed(precision)); + + // Support signed zero + if (fixedNum === 0) { + return 0; + } else { + return fixedNum; + } +} + +export function fixedLngLat(l: { lng: number; lat: number }, precision = 9) { + return { + lng: fixedNum(l.lng, precision), + lat: fixedNum(l.lat, precision), + }; +} + +export function fixedCoord(coord, precision = 10) { + return { + x: fixedNum(coord.x, precision), + y: fixedNum(coord.y, precision), + z: fixedNum(coord.z, precision), + }; +} diff --git a/packages/map/__tests__/libs/simulate_interaction.ts b/packages/map/__tests__/libs/simulate_interaction.ts new file mode 100644 index 00000000000..9cfeb29d651 --- /dev/null +++ b/packages/map/__tests__/libs/simulate_interaction.ts @@ -0,0 +1,108 @@ +function click(target: HTMLElement | Window | Element) { + const options = { bubbles: true }; + target.dispatchEvent(new MouseEvent('mousedown', options)); + target.dispatchEvent(new MouseEvent('mouseup', options)); + target.dispatchEvent(new MouseEvent('click', options)); +} + +function drag(target: HTMLElement | Window, mousedownOptions, mouseUpOptions) { + mousedownOptions = Object.assign({ bubbles: true }, mousedownOptions); + mouseUpOptions = Object.assign({ bubbles: true }, mouseUpOptions); + target.dispatchEvent(new MouseEvent('mousedown', mousedownOptions)); + target.dispatchEvent(new MouseEvent('mouseup', mouseUpOptions)); + target.dispatchEvent(new MouseEvent('click', mouseUpOptions)); +} + +function dragWithMove( + target: HTMLElement | Window, + start: { x: number; y: number }, + end: { x: number; y: number }, +) { + target.dispatchEvent( + new MouseEvent('mousedown', { bubbles: true, clientX: start.x, clientY: start.y }), + ); + document.dispatchEvent( + new MouseEvent('mousemove', { bubbles: true, buttons: 1, clientX: end.x, clientY: end.y }), + ); + target.dispatchEvent( + new MouseEvent('mouseup', { bubbles: true, clientX: end.x, clientY: end.y }), + ); +} + +function dblclick(target: HTMLElement | Window) { + const options = { bubbles: true }; + target.dispatchEvent(new MouseEvent('mousedown', options)); + target.dispatchEvent(new MouseEvent('mouseup', options)); + target.dispatchEvent(new MouseEvent('click', options)); + target.dispatchEvent(new MouseEvent('mousedown', options)); + target.dispatchEvent(new MouseEvent('mouseup', options)); + target.dispatchEvent(new MouseEvent('click', options)); + target.dispatchEvent(new MouseEvent('dblclick', options)); +} + +function keyFunctionFactory(event: string) { + return (target: HTMLElement | Window, options) => { + options = Object.assign({ bubbles: true }, options); + target.dispatchEvent(new KeyboardEvent(event, options)); + }; +} + +function mouseFunctionFactory(event: string) { + return (target: HTMLElement | Window, options?) => { + options = Object.assign({ bubbles: true }, options); + target.dispatchEvent(new MouseEvent(event, options)); + }; +} + +function wheelFunctionFactory(event: string) { + return (target: HTMLElement | Window, options) => { + options = Object.assign({ bubbles: true }, options); + target.dispatchEvent(new WheelEvent(event, options)); + }; +} + +function touchFunctionFactory(event: string) { + return (target: HTMLElement | Window, options?) => { + const defaultTouches = + event.endsWith('end') || event.endsWith('cancel') ? [] : [{ clientX: 0, clientY: 0 }]; + options = Object.assign({ bubbles: true, touches: defaultTouches }, options); + target.dispatchEvent(new TouchEvent(event, options)); + }; +} + +function focusBlueFunctionFactory(event: string) { + return (target: HTMLElement | Window) => { + const options = { bubbles: true }; + target.dispatchEvent(new FocusEvent(event, options)); + }; +} + +const events = { + click, + drag, + dragWithMove, + dblclick, + keydown: keyFunctionFactory('keydown'), + keyup: keyFunctionFactory('keyup'), + keypress: keyFunctionFactory('keypress'), + mouseup: mouseFunctionFactory('mouseup'), + mousedown: mouseFunctionFactory('mousedown'), + mouseover: mouseFunctionFactory('mouseover'), + mousemove: mouseFunctionFactory('mousemove'), + mouseout: mouseFunctionFactory('mouseout'), + contextmenu: mouseFunctionFactory('contextmenu'), + wheel: wheelFunctionFactory('wheel'), + mousewheel: wheelFunctionFactory('mousewheel'), + /** + * magic deltaY value that indicates the event is from a mouse wheel (rather than a trackpad) + */ + magicWheelZoomDelta: 4.000244140625, + touchstart: touchFunctionFactory('touchstart'), + touchend: touchFunctionFactory('touchend'), + touchmove: touchFunctionFactory('touchmove'), + touchcancel: touchFunctionFactory('touchcancel'), + focus: focusBlueFunctionFactory('focus'), + blur: focusBlueFunctionFactory('blur'), +}; + +export default events; diff --git a/packages/map/__tests__/libs/util.ts b/packages/map/__tests__/libs/util.ts new file mode 100644 index 00000000000..acdc2579ec3 --- /dev/null +++ b/packages/map/__tests__/libs/util.ts @@ -0,0 +1,69 @@ +import { Map } from '../../src/map/map'; +import { extend } from '../../src/map/util/util'; + +export function createMap(options?, callback?) { + const container = window.document.createElement('div'); + const defaultOptions = { + container, + interactive: false, + attributionControl: false, + trackResize: true, + }; + + Object.defineProperty(container, 'clientWidth', { value: 200, configurable: true }); + Object.defineProperty(container, 'clientHeight', { value: 200, configurable: true }); + + const map = new Map(extend(defaultOptions, options)); + if (callback) + map.on('load', () => { + callback(null, map); + }); + + return map; +} + +export function setPerformance() { + window.performance.mark = jest.fn(); + window.performance.clearMeasures = jest.fn(); + window.performance.clearMarks = jest.fn(); +} + +export function setMatchMedia() { + // https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom + Object.defineProperty(window, 'matchMedia', { + writable: true, + value: jest.fn().mockImplementation((query) => ({ + matches: false, + media: query, + onchange: null, + addListener: jest.fn(), // deprecated + removeListener: jest.fn(), // deprecated + addEventListener: jest.fn(), + removeEventListener: jest.fn(), + dispatchEvent: jest.fn(), + })), + }); +} + +function setResizeObserver() { + global.ResizeObserver = jest.fn().mockImplementation(() => ({ + observe: jest.fn(), + unobserve: jest.fn(), + disconnect: jest.fn(), + })); +} + +export function beforeMapTest() { + setPerformance(); + setMatchMedia(); + setResizeObserver(); +} + +/** + * This allows test to wait for a certain amount of time before continuing. + * @param milliseconds - the amount of time to wait in milliseconds + * @returns - a promise that resolves after the specified amount of time + */ +export const sleep = (milliseconds: number = 0) => { + return new Promise((resolve) => setTimeout(resolve, milliseconds)); +}; diff --git a/packages/map/__tests__/map.init.spec.ts b/packages/map/__tests__/map.init.spec.ts deleted file mode 100644 index 0309e3ae752..00000000000 --- a/packages/map/__tests__/map.init.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Map } from '../src/map'; -describe('Map', () => { - const el = document.createElement('div'); - el.id = 'test-div-id'; - // el.style.width = '500px'; - // el.style.height = '500px'; - el.style.background = '#aaa'; - let map: Map; - document.querySelector('body')?.appendChild(el); - beforeEach(() => { - map = new Map({ - container: el, - }); - }); - it('should resize correctly', () => { - // 创建Map的实例,将mock的Map传 - - // map.resize(); - map.setCenter([120.11114550000002, 30.27817071635984]); - map.setZoom(8.592359444611867); - - // 验证transform.resize方法是否被正确调用 - }); -}); diff --git a/packages/map/__tests__/map.spec.ts b/packages/map/__tests__/map.spec.ts deleted file mode 100644 index 0ae74eb8f3e..00000000000 --- a/packages/map/__tests__/map.spec.ts +++ /dev/null @@ -1,183 +0,0 @@ -import { Map } from '../src/map'; -describe('Map', () => { - const el = document.createElement('div'); - el.id = 'test-div-id'; - // el.style.width = '500px'; - // el.style.height = '500px'; - el.style.background = '#aaa'; - let map: Map; - document.querySelector('body')?.appendChild(el); - beforeEach(() => { - map = new Map({ - container: el, - }); - }); - it('should resize correctly', () => { - // 创建Map的实例,将mock的Map传 - - // map.resize(); - map.setCenter([121.434765, 31.256735]); - map.setZoom(14.83); - - // 验证transform.resize方法是否被正确调用 - }); - it('Map set zoom', () => { - map.setZoom(5); - expect(map.getZoom()).toEqual(5); - }); - it('Map set center', () => { - map.setCenter([120, 30]); - expect(map.getCenter()).toEqual({ lat: 30, lng: 120 }); - }); - it('Map set pitch', () => { - map.setPitch(10); - expect(map.getPitch()).toEqual(10); - }); - it('Map set Bearing', () => { - map.setBearing(10); - expect(map.getBearing()).toEqual(10); - }); - it('Map panTo ', () => { - map.panTo([121, 31], { animate: false }); - expect(map.getCenter()).toEqual({ lat: 31, lng: 121 }); - }); - it('Map panBy', () => { - map.panBy([10, 10], { animate: false }); - expect(map.getCenter().lng).toBeCloseTo(7.03, 2); - }); - it('Map zoomTo', () => { - map.zoomTo(10, { animate: false }); - expect(map.getZoom()).toEqual(10); - }); - it('Map zoomIn', () => { - map.setZoom(9); - map.zoomIn({ animate: false }); - expect(map.getZoom()).toEqual(10); - }); - it('Map zoomOut', () => { - map.setZoom(10); - map.zoomOut({ animate: false }); - expect(map.getZoom()).toEqual(9); - }); - it('Map setMaxZoom', () => { - map.setMaxZoom(15); - expect(map.getMaxZoom()).toEqual(15); - }); - it('Map setMinZoom', () => { - map.setMinZoom(5); - expect(map.getMinZoom()).toEqual(5); - }); - it('Map setMaxPitch', () => { - map.setMaxPitch(60); - expect(map.getMaxPitch()).toEqual(60); - }); - it('Map setMinPitch', () => { - map.setMinPitch(5); - expect(map.getMinPitch()).toEqual(5); - }); - // setPadding - it('Map setPadding', () => { - map.setPadding({ - top: 10, - bottom: 10, - left: 10, - right: 10, - }); - expect(map.getPadding()).toEqual({ bottom: 10, left: 10, right: 10, top: 10 }); - }); - // rotateTo - it('Map rotateTo', () => { - map.rotateTo(90); - expect(map.getBearing()).toEqual(-0); - }); - // resetNorth - it('Map resetNorth', () => { - map.resetNorth(); - expect(map.getBearing()).toEqual(-0); - }); - // resetNorthPitch - it('Map resetNorthPitch', () => { - map.resetNorthPitch(); - expect(map.getPitch()).toEqual(0); - }); - // fitBounds - it('Map fitBounds', () => { - map.fitBounds( - [ - [120, 30], - [121, 31], - ], - { animate: false }, - ); - expect(map.getZoom()).toBeCloseTo(7.5, 1); - }); - // snapToNorth - it('Map snapToNorth', () => { - map.snapToNorth(); - expect(map.getBearing()).toEqual(-0); - }); - //jumpTo - it('Map jumpTo', () => { - map.jumpTo( - { - center: [120, 30], - zoom: 10, - bearing: 90, - pitch: 60, - }, - { - animate: false, - }, - ); - expect(map.getCenter()).toEqual({ lat: 30, lng: 120 }); - expect(map.getZoom()).toEqual(10); - expect(map.getBearing()).toEqual(90); - expect(map.getPitch()).toEqual(60); - }); - - // map getContainer - it('Map getContainer', () => { - expect(map.getContainer()).toEqual(el); - }); - // getcanvas - it('Map getCanvas', () => { - expect(map.getCanvas()).toBeUndefined(); - }); - // project - it('Map project', () => { - expect(map.project([120, 30]).x).toBeCloseTo(370.6, 0); - expect(map.project([120, 30]).y).toBeCloseTo(105.2, 1); - }); - // unproject - it('Map unproject', () => { - expect(map.unproject([100, 100]).lng).toBeCloseTo(-70.3, 1); - expect(map.unproject([100, 100]).lat).toBeCloseTo(33.1, 1); - }); - // getbounds - it('Map getBounds', () => { - expect(map.getBounds().toArray()).toEqual([ - [-140.6250000000022, -71.96538769913126], - [140.62499999999886, 71.96538769913161], - ]); - }); - // map remove - it('Map remove', () => { - map.remove(); - expect(map.getCanvasContainer()).toEqual(null); - }); - // getMaxBounds - it('Map getMaxBounds', () => { - expect(map.getMaxBounds()).toEqual(null); - }); - // // setMaxBounds - it('Map setMaxBounds', () => { - map.setMaxBounds([ - [120, 30], - [121, 31], - ]); - expect(map.getMaxBounds()?.toArray()).toEqual([ - [120, 30], - [121, 31], - ]); - }); -}); diff --git a/packages/map/__tests__/map/map_animation.spec.ts b/packages/map/__tests__/map/map_animation.spec.ts new file mode 100644 index 00000000000..7e05e46c825 --- /dev/null +++ b/packages/map/__tests__/map/map_animation.spec.ts @@ -0,0 +1,62 @@ +import simulate from '../libs/simulate_interaction'; +import { beforeMapTest, createMap } from '../libs/util'; + +beforeEach(() => { + beforeMapTest(); + global.fetch = null; +}); + +test('stops camera animation on touchstart when interactive', () => { + const map = createMap({ interactive: true }); + map.flyTo({ center: [200, 0], duration: 100 }); + + simulate.touchstart(map.getCanvasContainer(), { + touches: [{ target: map.getCanvasContainer(), clientX: 0, clientY: 0 }], + }); + expect(map.isEasing()).toBe(false); + + map.remove(); +}); + +test('continues camera animation on touchstart when non-interactive', () => { + const map = createMap({ interactive: false }); + map.flyTo({ center: [200, 0], duration: 100 }); + + simulate.touchstart(map.getCanvasContainer()); + expect(map.isEasing()).toBe(true); + + map.remove(); +}); + +test('continues camera animation on resize', () => { + const map = createMap(), + container = map.getContainer(); + + map.flyTo({ center: [200, 0], duration: 100 }); + + Object.defineProperty(container, 'clientWidth', { value: 250 }); + Object.defineProperty(container, 'clientHeight', { value: 250 }); + map.resize(); + + expect(map.isMoving()).toBeTruthy(); +}); + +test('stops camera animation on mousedown when interactive', () => { + const map = createMap({ interactive: true }); + map.flyTo({ center: [200, 0], duration: 100 }); + + simulate.mousedown(map.getCanvasContainer()); + expect(map.isEasing()).toBe(false); + + map.remove(); +}); + +test('continues camera animation on mousedown when non-interactive', () => { + const map = createMap({ interactive: false }); + map.flyTo({ center: [200, 0], duration: 100 }); + + simulate.mousedown(map.getCanvasContainer()); + expect(map.isEasing()).toBe(true); + + map.remove(); +}); diff --git a/packages/map/__tests__/map/map_basic.spec.ts b/packages/map/__tests__/map/map_basic.spec.ts new file mode 100644 index 00000000000..166cbc5ec74 --- /dev/null +++ b/packages/map/__tests__/map/map_basic.spec.ts @@ -0,0 +1,77 @@ +import type { MapOptions } from '../../src/map/map'; +import { Map } from '../../src/map/map'; +import { fixedLngLat } from '../libs/fixed'; +import { beforeMapTest, createMap } from '../libs/util'; + +beforeEach(() => { + beforeMapTest(); + global.fetch = null; +}); + +describe('Map', () => { + test('constructor', () => { + const map = createMap({ interactive: true, style: null }); + expect(map.getContainer()).toBeTruthy(); + expect(map.boxZoom.isEnabled()).toBeTruthy(); + expect(map.doubleClickZoom.isEnabled()).toBeTruthy(); + expect(map.dragPan.isEnabled()).toBeTruthy(); + expect(map.dragRotate.isEnabled()).toBeTruthy(); + expect(map.keyboard.isEnabled()).toBeTruthy(); + expect(map.scrollZoom.isEnabled()).toBeTruthy(); + expect(map.touchZoomRotate.isEnabled()).toBeTruthy(); + expect(() => { + new Map({ + container: 'anElementIdWhichDoesNotExistInTheDocument', + } as any as MapOptions); + }).toThrow(new Error("Container 'anElementIdWhichDoesNotExistInTheDocument' not found.")); + }); + + test('bad map-specific token breaks map', () => { + const container = window.document.createElement('div'); + Object.defineProperty(container, 'offsetWidth', { value: 512 }); + Object.defineProperty(container, 'offsetHeight', { value: 512 }); + createMap(); + //t.error(); + }); + + test('#remove', () => { + const map = createMap(); + + expect(map.getContainer().childNodes).toHaveLength(1); + map.remove(); + expect(map.getContainer().childNodes).toHaveLength(0); + }); + + test('#project', () => { + const map = createMap(); + expect(map.project([0, 0])).toEqual({ x: 100, y: 100 }); + }); + + test('#unproject', () => { + const map = createMap(); + expect(fixedLngLat(map.unproject([100, 100]))).toEqual({ lng: 0, lat: 0 }); + }); + + describe('cooperativeGestures option', () => { + test('cooperativeGesture container element is hidden from a11y tree', () => { + const map = createMap({ cooperativeGestures: true }); + expect( + map + .getContainer() + .querySelector('.l7-cooperative-gesture-screen') + .getAttribute('aria-hidden'), + ).toBeTruthy(); + }); + + test('cooperativeGesture container element is not available when cooperativeGestures not initialized', () => { + const map = createMap({ cooperativeGestures: false }); + expect(map.getContainer().querySelector('.l7-cooperative-gesture-screen')).toBeFalsy(); + }); + + test('cooperativeGesture container element is not available when cooperativeGestures disabled', () => { + const map = createMap({ cooperativeGestures: true }); + map.cooperativeGestures.disable(); + expect(map.getContainer().querySelector('.l7-cooperative-gesture-screen')).toBeFalsy(); + }); + }); +}); diff --git a/packages/map/__tests__/map/map_bounds.spec.ts b/packages/map/__tests__/map/map_bounds.spec.ts new file mode 100644 index 00000000000..e525f04daab --- /dev/null +++ b/packages/map/__tests__/map/map_bounds.spec.ts @@ -0,0 +1,152 @@ +import type { LngLatBoundsLike } from '../../src/map/geo/lng_lat_bounds'; +import { fixedLngLat, fixedNum } from '../libs/fixed'; +import { beforeMapTest, createMap } from '../libs/util'; + +beforeEach(() => { + beforeMapTest(); + global.fetch = null; +}); + +test('initial bounds in constructor options', () => { + const container = window.document.createElement('div'); + Object.defineProperty(container, 'offsetWidth', { value: 512 }); + Object.defineProperty(container, 'offsetHeight', { value: 512 }); + + const bounds = [ + [-133, 16], + [-68, 50], + ]; + const map = createMap({ container, bounds }); + + expect(fixedLngLat(map.getCenter(), 4)).toEqual({ lng: -100.5, lat: 34.7171 }); + expect(fixedNum(map.getZoom(), 3)).toBe(2.113); +}); + +test('initial bounds options in constructor options', () => { + const bounds = [ + [-133, 16], + [-68, 50], + ]; + + const map = (fitBoundsOptions) => { + const container = window.document.createElement('div'); + Object.defineProperty(container, 'offsetWidth', { value: 512 }); + Object.defineProperty(container, 'offsetHeight', { value: 512 }); + return createMap({ container, bounds, fitBoundsOptions }); + }; + + const unpadded = map(undefined); + const padded = map({ padding: 100 }); + + expect(unpadded.getZoom() > padded.getZoom()).toBeTruthy(); +}); + +describe('#getBounds', () => { + test('getBounds', () => { + const map = createMap({ zoom: 0 }); + expect(parseFloat(map.getBounds().getCenter().lng.toFixed(10))).toBe(-0); + expect(parseFloat(map.getBounds().getCenter().lat.toFixed(10))).toBe(0); + + expect(toFixed(map.getBounds().toArray())).toEqual( + toFixed([ + [-70.31249999999976, -57.326521225216965], + [70.31249999999977, 57.32652122521695], + ]), + ); + }); + + test('rotated bounds', () => { + const map = createMap({ zoom: 1, bearing: 45 }); + expect( + toFixed([ + [-49.718445552178764, -44.44541580601936], + [49.7184455522, 44.445415806019355], + ]), + ).toEqual(toFixed(map.getBounds().toArray())); + + map.setBearing(135); + expect( + toFixed([ + [-49.718445552178764, -44.44541580601936], + [49.7184455522, 44.445415806019355], + ]), + ).toEqual(toFixed(map.getBounds().toArray())); + }); + + function toFixed(bounds) { + const n = 10; + return [ + [normalizeFixed(bounds[0][0], n), normalizeFixed(bounds[0][1], n)], + [normalizeFixed(bounds[1][0], n), normalizeFixed(bounds[1][1], n)], + ]; + } + + function normalizeFixed(num, n) { + // workaround for "-0.0000000000" ≠ "0.0000000000" + return parseFloat(num.toFixed(n)).toFixed(n); + } +}); + +describe('#setMaxBounds', () => { + test('constrains map bounds', () => { + const map = createMap({ zoom: 0 }); + map.setMaxBounds([ + [-130.4297, 50.0642], + [-61.52344, 24.20688], + ]); + expect( + toFixed([ + [-130.4297, 7.0136641176], + [-61.52344, 60.2398142283], + ]), + ).toEqual(toFixed(map.getBounds().toArray())); + }); + + test('when no argument is passed, map bounds constraints are removed', () => { + const map = createMap({ zoom: 0 }); + map.setMaxBounds([ + [-130.4297, 50.0642], + [-61.52344, 24.20688], + ]); + expect( + toFixed([ + [-166.28906999999964, -27.6835270554], + [-25.664070000000066, 73.8248206697], + ]), + ).toEqual(toFixed(map.setMaxBounds(null).setZoom(0).getBounds().toArray())); + }); + + test('should not zoom out farther than bounds', () => { + const map = createMap(); + map.setMaxBounds([ + [-130.4297, 50.0642], + [-61.52344, 24.20688], + ]); + expect(map.setZoom(0).getZoom()).not.toBe(0); + }); + + function toFixed(bounds) { + const n = 9; + return [ + [bounds[0][0].toFixed(n), bounds[0][1].toFixed(n)], + [bounds[1][0].toFixed(n), bounds[1][1].toFixed(n)], + ]; + } +}); + +describe('#getMaxBounds', () => { + test('returns null when no bounds set', () => { + const map = createMap({ zoom: 0 }); + expect(map.getMaxBounds()).toBeNull(); + }); + + test('returns bounds', () => { + const map = createMap({ zoom: 0 }); + const bounds = [ + [-130.4297, 50.0642], + [-61.52344, 24.20688], + ] as LngLatBoundsLike; + map.setMaxBounds(bounds); + expect(map.getMaxBounds().toArray()).toEqual(bounds); + }); +}); diff --git a/packages/map/__tests__/map/map_disable_handlers.spec.ts b/packages/map/__tests__/map/map_disable_handlers.spec.ts new file mode 100644 index 00000000000..607c0e178d3 --- /dev/null +++ b/packages/map/__tests__/map/map_disable_handlers.spec.ts @@ -0,0 +1,37 @@ +import { beforeMapTest, createMap } from '../libs/util'; + +beforeEach(() => { + beforeMapTest(); + global.fetch = null; +}); + +test('disable all handlers', () => { + const map = createMap({ interactive: false }); + + expect(map.boxZoom.isEnabled()).toBeFalsy(); + expect(map.doubleClickZoom.isEnabled()).toBeFalsy(); + expect(map.dragPan.isEnabled()).toBeFalsy(); + expect(map.dragRotate.isEnabled()).toBeFalsy(); + expect(map.keyboard.isEnabled()).toBeFalsy(); + expect(map.scrollZoom.isEnabled()).toBeFalsy(); + expect(map.touchZoomRotate.isEnabled()).toBeFalsy(); +}); + +const handlerNames = [ + 'scrollZoom', + 'boxZoom', + 'dragRotate', + 'dragPan', + 'keyboard', + 'doubleClickZoom', + 'touchZoomRotate', +]; +handlerNames.forEach((handlerName) => { + test(`disable "${handlerName}" handler`, () => { + const options = {}; + options[handlerName] = false; + const map = createMap(options); + + expect(map[handlerName].isEnabled()).toBeFalsy(); + }); +}); diff --git a/packages/map/__tests__/map/map_events.spec.ts b/packages/map/__tests__/map/map_events.spec.ts new file mode 100644 index 00000000000..310a17b21ca --- /dev/null +++ b/packages/map/__tests__/map/map_events.spec.ts @@ -0,0 +1,254 @@ +import { ErrorEvent } from '../../src/map/util/evented'; +import simulate from '../libs/simulate_interaction'; +import { beforeMapTest, createMap } from '../libs/util'; + +function assertNotAny() {} + +beforeEach(() => { + beforeMapTest(); +}); + +describe('map events', () => { + test('Map#on adds a non-delegated event listener', () => { + const map = createMap(); + const spy = jest.fn(function (e) { + expect(this).toBe(map); + expect(e.type).toBe('click'); + }); + + map.on('click', spy); + simulate.click(map.getCanvasContainer()); + + expect(spy).toHaveBeenCalledTimes(1); + }); + + test('Map#off removes a non-delegated event listener', () => { + const map = createMap(); + const spy = jest.fn(); + + map.on('click', spy); + map.off('click', spy); + simulate.click(map.getCanvasContainer()); + + expect(spy).not.toHaveBeenCalled(); + }); + + test("Map#on calls an event listener with no type arguments, defaulting to 'unknown' originalEvent type", () => { + const map = createMap(); + + const handler = { + onMove: function onMove() {}, + }; + + jest.spyOn(handler, 'onMove'); + + map.on('move', () => handler.onMove()); + map.jumpTo({ center: { lng: 10, lat: 10 } }); + + expect(handler.onMove).toHaveBeenCalledTimes(1); + }); + + test('Map#on allows a listener to infer the event type ', () => { + const map = createMap(); + + const spy = jest.fn(); + map.on('mousemove', (event) => { + assertNotAny(); + const { lng, lat } = event.lngLat; + spy({ lng, lat }); + }); + + simulate.mousemove(map.getCanvasContainer()); + expect(spy).toHaveBeenCalledTimes(1); + }); + + test("Map#off calls an event listener with no type arguments, defaulting to 'unknown' originalEvent type", () => { + const map = createMap(); + + const handler = { + onMove: function onMove() {}, + }; + + jest.spyOn(handler, 'onMove'); + + map.off('move', () => handler.onMove()); + map.jumpTo({ center: { lng: 10, lat: 10 } }); + + expect(handler.onMove).toHaveBeenCalledTimes(0); + }); + + test('Map#off allows a listener to infer the event type ', () => { + const map = createMap(); + + const spy = jest.fn(); + map.off('mousemove', (event) => { + assertNotAny(); + const { lng, lat } = event.lngLat; + spy({ lng, lat }); + }); + + simulate.mousemove(map.getCanvasContainer()); + expect(spy).toHaveBeenCalledTimes(0); + }); + + test("Map#once calls an event listener with no type arguments, defaulting to 'unknown' originalEvent type", () => { + const map = createMap(); + + const handler = { + onMoveOnce: function onMoveOnce() {}, + }; + + jest.spyOn(handler, 'onMoveOnce'); + + map.once('move', () => handler.onMoveOnce()); + map.jumpTo({ center: { lng: 10, lat: 10 } }); + + expect(handler.onMoveOnce).toHaveBeenCalledTimes(1); + }); + + test('Map#once allows a listener to infer the event type ', () => { + const map = createMap(); + + const spy = jest.fn(); + map.once('mousemove', (event) => { + assertNotAny(); + const { lng, lat } = event.lngLat; + spy({ lng, lat }); + }); + + simulate.mousemove(map.getCanvasContainer()); + expect(spy).toHaveBeenCalledTimes(1); + }); + + test('Map#on mousedown can have default behavior prevented and still fire subsequent click event', () => { + const map = createMap(); + + map.on('mousedown', (e) => e.preventDefault()); + + const click = jest.fn(); + map.on('click', click); + + simulate.click(map.getCanvasContainer()); + expect(click).toHaveBeenCalled(); + + map.remove(); + }); + + test("Map#on mousedown doesn't fire subsequent click event if mousepos changes", () => { + const map = createMap(); + + map.on('mousedown', (e) => e.preventDefault()); + + const click = jest.fn(); + map.on('click', click); + const canvas = map.getCanvasContainer(); + + simulate.drag(canvas, {}, { clientX: 100, clientY: 100 }); + expect(click).not.toHaveBeenCalled(); + + map.remove(); + }); + + test('Map#on mousedown fires subsequent click event if mouse position changes less than click tolerance', () => { + const map = createMap({ clickTolerance: 4 }); + + map.on('mousedown', (e) => e.preventDefault()); + + const click = jest.fn(); + map.on('click', click); + const canvas = map.getCanvasContainer(); + + simulate.drag(canvas, { clientX: 100, clientY: 100 }, { clientX: 100, clientY: 103 }); + expect(click).toHaveBeenCalled(); + + map.remove(); + }); + + test('Map#on mousedown does not fire subsequent click event if mouse position changes more than click tolerance', () => { + const map = createMap({ clickTolerance: 4 }); + + map.on('mousedown', (e) => e.preventDefault()); + + const click = jest.fn(); + map.on('click', click); + const canvas = map.getCanvasContainer(); + + simulate.drag(canvas, { clientX: 100, clientY: 100 }, { clientX: 100, clientY: 104 }); + expect(click).not.toHaveBeenCalled(); + + map.remove(); + }); + + test('Map#on click fires subsequent click event if there is no corresponding mousedown/mouseup event', () => { + const map = createMap({ clickTolerance: 4 }); + + const click = jest.fn(); + map.on('click', click); + const canvas = map.getCanvasContainer(); + + const event = new MouseEvent('click', { bubbles: true, clientX: 100, clientY: 100 }); + canvas.dispatchEvent(event); + expect(click).toHaveBeenCalled(); + + map.remove(); + }); + + test('Map#isMoving() returns false in mousedown/mouseup/click with no movement', () => { + const map = createMap({ interactive: true, clickTolerance: 4 }); + let mousedown, mouseup, click; + map.on('mousedown', () => { + mousedown = map.isMoving(); + }); + map.on('mouseup', () => { + mouseup = map.isMoving(); + }); + map.on('click', () => { + click = map.isMoving(); + }); + + const canvas = map.getCanvasContainer(); + + canvas.dispatchEvent( + new MouseEvent('mousedown', { bubbles: true, clientX: 100, clientY: 100 }), + ); + expect(mousedown).toBe(false); + map._renderTaskQueue.run(); + expect(mousedown).toBe(false); + + canvas.dispatchEvent(new MouseEvent('mouseup', { bubbles: true, clientX: 100, clientY: 100 })); + expect(mouseup).toBe(false); + map._renderTaskQueue.run(); + expect(mouseup).toBe(false); + + canvas.dispatchEvent(new MouseEvent('click', { bubbles: true, clientX: 100, clientY: 100 })); + expect(click).toBe(false); + map._renderTaskQueue.run(); + expect(click).toBe(false); + + map.remove(); + }); + + describe('error event', () => { + test('logs errors to console when it has NO listeners', () => { + // to avoid seeing error in the console in Jest + let stub = jest.spyOn(console, 'error').mockImplementation(() => {}); + const map = createMap(); + stub.mockReset(); + stub = jest.spyOn(console, 'error').mockImplementation(() => {}); + const error = new Error('test'); + map.fire(new ErrorEvent(error)); + expect(stub).toHaveBeenCalledTimes(1); + expect(stub.mock.calls[0][0]).toBe(error); + }); + + test('calls listeners', (done) => { + const map = createMap(); + const error = new Error('test'); + map.on('error', (event) => { + expect(event.error).toBe(error); + done(); + }); + map.fire(new ErrorEvent(error)); + }); + }); +}); diff --git a/packages/map/__tests__/map/map_is_moving.spec.ts b/packages/map/__tests__/map/map_is_moving.spec.ts new file mode 100644 index 00000000000..9018fa9ccb5 --- /dev/null +++ b/packages/map/__tests__/map/map_is_moving.spec.ts @@ -0,0 +1,177 @@ +import { Map } from '../../src/map/map'; +import { browser } from '../../src/map/util/browser'; +import { DOM } from '../../src/map/util/dom'; +import simulate from '../libs/simulate_interaction'; + +import { beforeMapTest } from '../libs/util'; + +let map; + +function createMap() { + return new Map({ container: DOM.create('div', '', window.document.body) }); +} + +beforeEach(() => { + beforeMapTest(); + map = createMap(); +}); + +afterEach(() => { + map.remove(); +}); + +describe('Map#isMoving', () => { + // MouseEvent.buttons + const buttons = 1; + + test('returns false by default', () => { + expect(map.isMoving()).toBe(false); + }); + + test('returns true during a camera zoom animation', (done) => { + map.on('zoomstart', () => { + expect(map.isMoving()).toBe(true); + }); + + map.on('zoomend', () => { + expect(map.isMoving()).toBe(false); + done(); + }); + + map.zoomTo(5, { duration: 0 }); + }); + + test('returns true when drag panning', (done) => { + map.on('movestart', () => { + expect(map.isMoving()).toBe(true); + }); + map.on('dragstart', () => { + expect(map.isMoving()).toBe(true); + }); + + map.on('dragend', () => { + expect(map.isMoving()).toBe(false); + }); + map.on('moveend', () => { + expect(map.isMoving()).toBe(false); + done(); + }); + + simulate.mousedown(map.getCanvasContainer()); + map._renderTaskQueue.run(); + + simulate.mousemove(map.getCanvasContainer(), { buttons, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + + simulate.mouseup(map.getCanvasContainer()); + map._renderTaskQueue.run(); + }); + + test('returns true when drag rotating', (done) => { + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockImplementation(() => { + return 0; + }); + + map.on('movestart', () => { + expect(map.isMoving()).toBe(true); + }); + + map.on('rotatestart', () => { + expect(map.isMoving()).toBe(true); + }); + + map.on('rotateend', () => { + expect(map.isMoving()).toBe(false); + }); + + map.on('moveend', () => { + expect(map.isMoving()).toBe(false); + done(); + }); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2 }); + map._renderTaskQueue.run(); + + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 2 }); + map._renderTaskQueue.run(); + }); + + test('returns true when scroll zooming', (done) => { + map.on('zoomstart', () => { + expect(map.isMoving()).toBe(true); + }); + + map.on('zoomend', () => { + expect(map.isMoving()).toBe(false); + done(); + }); + + let now = 0; + jest.spyOn(browser, 'now').mockImplementation(() => { + return now; + }); + + simulate.wheel(map.getCanvasContainer(), { + type: 'wheel', + deltaY: -simulate.magicWheelZoomDelta, + }); + map._renderTaskQueue.run(); + + now += 400; + setTimeout(() => { + map._renderTaskQueue.run(); + }, 400); + }); + + test('returns true when drag panning and scroll zooming interleave', (done) => { + map.on('dragstart', () => { + expect(map.isMoving()).toBe(true); + }); + + map.on('zoomstart', () => { + expect(map.isMoving()).toBe(true); + }); + + map.on('zoomend', () => { + expect(map.isMoving()).toBe(true); + simulate.mouseup(map.getCanvasContainer()); + setTimeout(() => { + map._renderTaskQueue.run(); + done(); + }); + }); + + map.on('dragend', () => { + expect(map.isMoving()).toBe(false); + }); + + // The following should trigger the above events, where a zoomstart/zoomend + // pair is nested within a dragstart/dragend pair. + + simulate.mousedown(map.getCanvasContainer()); + map._renderTaskQueue.run(); + + simulate.mousemove(map.getCanvasContainer(), { buttons, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + + let now = 0; + jest.spyOn(browser, 'now').mockImplementation(() => { + return now; + }); + + simulate.wheel(map.getCanvasContainer(), { + type: 'wheel', + deltaY: -simulate.magicWheelZoomDelta, + }); + map._renderTaskQueue.run(); + + now += 400; + setTimeout(() => { + map._renderTaskQueue.run(); + }, 400); + }); +}); diff --git a/packages/map/__tests__/map/map_is_rotating.spec.ts b/packages/map/__tests__/map/map_is_rotating.spec.ts new file mode 100644 index 00000000000..e9f95a9a1f0 --- /dev/null +++ b/packages/map/__tests__/map/map_is_rotating.spec.ts @@ -0,0 +1,64 @@ +import { Map } from '../../src/map/map'; +import { browser } from '../../src/map/util/browser'; +import { DOM } from '../../src/map/util/dom'; +import simulate from '../libs/simulate_interaction'; +import { beforeMapTest } from '../libs/util'; + +let map; + +function createMap() { + return new Map({ container: DOM.create('div', '', window.document.body) }); +} + +beforeEach(() => { + beforeMapTest(); + map = createMap(); +}); + +afterEach(() => { + map.remove(); +}); + +describe('Map#isRotating', () => { + test('returns false by default', () => { + expect(map.isRotating()).toBe(false); + }); + + test('returns true during a camera rotate animation', (done) => { + map.on('rotatestart', () => { + expect(map.isRotating()).toBe(true); + }); + + map.on('rotateend', () => { + expect(map.isRotating()).toBe(false); + done(); + }); + + map.rotateTo(5, { duration: 0 }); + }); + + test('returns true when drag rotating', (done) => { + // Prevent inertial rotation. + jest.spyOn(browser, 'now').mockImplementation(() => { + return 0; + }); + + map.on('rotatestart', () => { + expect(map.isRotating()).toBe(true); + }); + + map.on('rotateend', () => { + expect(map.isRotating()).toBe(false); + done(); + }); + + simulate.mousedown(map.getCanvasContainer(), { buttons: 2, button: 2 }); + map._renderTaskQueue.run(); + + simulate.mousemove(map.getCanvasContainer(), { buttons: 2, clientX: 10, clientY: 10 }); + map._renderTaskQueue.run(); + + simulate.mouseup(map.getCanvasContainer(), { buttons: 0, button: 2 }); + map._renderTaskQueue.run(); + }); +}); diff --git a/packages/map/__tests__/map/map_is_zooming.spec.ts b/packages/map/__tests__/map/map_is_zooming.spec.ts new file mode 100644 index 00000000000..ca03857a904 --- /dev/null +++ b/packages/map/__tests__/map/map_is_zooming.spec.ts @@ -0,0 +1,93 @@ +import { Map } from '../../src/map/map'; +import { browser } from '../../src/map/util/browser'; +import { DOM } from '../../src/map/util/dom'; +import simulate from '../libs/simulate_interaction'; +import { beforeMapTest } from '../libs/util'; + +function createMap() { + return new Map({ container: DOM.create('div', '', window.document.body) }); +} + +beforeEach(() => { + beforeMapTest(); +}); + +describe('Map#isZooming', () => { + test('returns false by default', (done) => { + const map = createMap(); + expect(map.isZooming()).toBe(false); + map.remove(); + done(); + }); + + test('returns true during a camera zoom animation', (done) => { + const map = createMap(); + + map.on('zoomstart', () => { + expect(map.isZooming()).toBe(true); + }); + + map.on('zoomend', () => { + expect(map.isZooming()).toBe(false); + map.remove(); + done(); + }); + + map.zoomTo(5, { duration: 0 }); + }); + + test('returns true when scroll zooming', (done) => { + const map = createMap(); + + map.on('zoomstart', () => { + expect(map.isZooming()).toBe(true); + }); + + map.on('zoomend', () => { + expect(map.isZooming()).toBe(false); + map.remove(); + done(); + }); + + let now = 0; + jest.spyOn(browser, 'now').mockImplementation(() => { + return now; + }); + + simulate.wheel(map.getCanvasContainer(), { + type: 'wheel', + deltaY: -simulate.magicWheelZoomDelta, + }); + map._renderTaskQueue.run(); + + now += 400; + setTimeout(() => { + map._renderTaskQueue.run(); + }, 400); + }); + + test('returns true when double-click zooming', (done) => { + const map = createMap(); + + map.on('zoomstart', () => { + expect(map.isZooming()).toBe(true); + }); + + map.on('zoomend', () => { + expect(map.isZooming()).toBe(false); + map.remove(); + done(); + }); + + let now = 0; + jest.spyOn(browser, 'now').mockImplementation(() => { + return now; + }); + + simulate.dblclick(map.getCanvasContainer()); + map._renderTaskQueue.run(); + + now += 500; + map._renderTaskQueue.run(); + }); +}); diff --git a/packages/map/__tests__/map/map_pitch.spec.ts b/packages/map/__tests__/map/map_pitch.spec.ts new file mode 100644 index 00000000000..e02f79d8595 --- /dev/null +++ b/packages/map/__tests__/map/map_pitch.spec.ts @@ -0,0 +1,90 @@ +import { beforeMapTest, createMap } from '../libs/util'; + +beforeEach(() => { + beforeMapTest(); + global.fetch = null; +}); + +test('#setMinPitch', () => { + const map = createMap({ pitch: 20 }); + map.setMinPitch(10); + map.setPitch(0); + expect(map.getPitch()).toBe(10); +}); + +test('unset minPitch', () => { + const map = createMap({ minPitch: 20 }); + map.setMinPitch(null); + map.setPitch(0); + expect(map.getPitch()).toBe(0); +}); + +test('#getMinPitch', () => { + const map = createMap({ pitch: 0 }); + expect(map.getMinPitch()).toBe(0); + map.setMinPitch(10); + expect(map.getMinPitch()).toBe(10); +}); + +test('ignore minPitchs over maxPitch', () => { + const map = createMap({ pitch: 0, maxPitch: 10 }); + expect(() => { + map.setMinPitch(20); + }).toThrow(); + map.setPitch(0); + expect(map.getPitch()).toBe(0); +}); + +test('#setMaxPitch', () => { + const map = createMap({ pitch: 0 }); + map.setMaxPitch(10); + map.setPitch(20); + expect(map.getPitch()).toBe(10); +}); + +test('unset maxPitch', () => { + const map = createMap({ maxPitch: 10 }); + map.setMaxPitch(null); + map.setPitch(20); + expect(map.getPitch()).toBe(20); +}); + +test('#getMaxPitch', () => { + const map = createMap({ pitch: 0 }); + expect(map.getMaxPitch()).toBe(60); + map.setMaxPitch(10); + expect(map.getMaxPitch()).toBe(10); +}); + +test('ignore maxPitchs over minPitch', () => { + const map = createMap({ minPitch: 10 }); + expect(() => { + map.setMaxPitch(0); + }).toThrow(); + map.setPitch(10); + expect(map.getPitch()).toBe(10); +}); + +test('throw on maxPitch smaller than minPitch at init', () => { + expect(() => { + createMap({ minPitch: 10, maxPitch: 5 }); + }).toThrow(new Error('maxPitch must be greater than or equal to minPitch')); +}); + +test('throw on maxPitch smaller than minPitch at init with falsey maxPitch', () => { + expect(() => { + createMap({ minPitch: 1, maxPitch: 0 }); + }).toThrow(new Error('maxPitch must be greater than or equal to minPitch')); +}); + +test('throw on maxPitch greater than valid maxPitch at init', () => { + expect(() => { + createMap({ maxPitch: 90 }); + }).toThrow(new Error('maxPitch must be less than or equal to 85')); +}); + +test('throw on minPitch less than valid minPitch at init', () => { + expect(() => { + createMap({ minPitch: -10 }); + }).toThrow(new Error('minPitch must be greater than or equal to 0')); +}); diff --git a/packages/map/__tests__/map/map_request_render_frame.spec.ts b/packages/map/__tests__/map/map_request_render_frame.spec.ts new file mode 100644 index 00000000000..0907f553dcd --- /dev/null +++ b/packages/map/__tests__/map/map_request_render_frame.spec.ts @@ -0,0 +1,34 @@ +import { beforeMapTest, createMap } from '../libs/util'; + +beforeEach(() => { + beforeMapTest(); +}); + +describe('requestRenderFrame', () => { + test('Map#_requestRenderFrame should not schedule a render frame before style load', () => { + const map = createMap(); + const spy = jest.spyOn(map, 'triggerRepaint'); + map._requestRenderFrame(() => {}); + expect(spy).toHaveBeenCalledTimes(1); + map.remove(); + }); + + test('Map#_requestRenderFrame queues a task for the next render frame', async () => { + const map = createMap(); + const cb = jest.fn(); + map._requestRenderFrame(cb); + await map.once('render'); + expect(cb).toHaveBeenCalledTimes(1); + map.remove(); + }); + + test('Map#_cancelRenderFrame cancels a queued task', async () => { + const map = createMap(); + const cb = jest.fn(); + const id = map._requestRenderFrame(cb); + map._cancelRenderFrame(id); + await map.once('render'); + expect(cb).toHaveBeenCalledTimes(0); + map.remove(); + }); +}); diff --git a/packages/map/__tests__/map/map_resize.spec.ts b/packages/map/__tests__/map/map_resize.spec.ts new file mode 100644 index 00000000000..705f1e6bb40 --- /dev/null +++ b/packages/map/__tests__/map/map_resize.spec.ts @@ -0,0 +1,102 @@ +import { beforeMapTest, createMap, sleep } from '../libs/util'; + +beforeEach(() => { + beforeMapTest(); + global.fetch = null; +}); + +describe('#resize', () => { + test('sets width and height from container clients', () => { + const map = createMap(), + container = map.getContainer(); + + Object.defineProperty(container, 'clientWidth', { value: 250 }); + Object.defineProperty(container, 'clientHeight', { value: 250 }); + map.resize(); + + expect(map.transform.width).toBe(250); + expect(map.transform.height).toBe(250); + }); + + test('fires movestart, move, resize, and moveend events', () => { + const map = createMap(), + events = []; + + (['movestart', 'move', 'resize', 'moveend'] as any).forEach((event) => { + map.on(event, (e) => { + events.push(e.type); + }); + }); + + map.resize(); + expect(events).toEqual(['movestart', 'move', 'resize', 'moveend']); + }); + + test('listen to window resize event', () => { + const spy = jest.fn(); + global.ResizeObserver = jest.fn().mockImplementation(() => ({ + observe: spy, + })); + + createMap(); + + expect(spy).toHaveBeenCalled(); + }); + + test('do not resize if trackResize is false', () => { + let observerCallback: Function = null; + global.ResizeObserver = jest.fn().mockImplementation((c) => ({ + observe: () => { + observerCallback = c; + }, + })); + + const map = createMap({ trackResize: false }); + + const spyA = jest.spyOn(map, 'stop'); + const spyB = jest.spyOn(map, '_update'); + const spyC = jest.spyOn(map, 'resize'); + + observerCallback(); + + expect(spyA).not.toHaveBeenCalled(); + expect(spyB).not.toHaveBeenCalled(); + expect(spyC).not.toHaveBeenCalled(); + }); + + test('do resize if trackResize is true (default)', async () => { + let observerCallback: Function = null; + global.ResizeObserver = jest.fn().mockImplementation((c) => ({ + observe: () => { + observerCallback = c; + }, + })); + + const map = createMap(); + + const updateSpy = jest.spyOn(map, '_update'); + const resizeSpy = jest.spyOn(map, 'resize'); + + // The initial "observe" event fired by ResizeObserver should be captured/muted + // in the map constructor + + observerCallback(); + expect(updateSpy).not.toHaveBeenCalled(); + expect(resizeSpy).not.toHaveBeenCalled(); + + // The next "observe" event should fire a resize / _update + + observerCallback(); + expect(updateSpy).toHaveBeenCalled(); + expect(resizeSpy).toHaveBeenCalledTimes(1); + + // Additional "observe" events should be throttled + observerCallback(); + observerCallback(); + observerCallback(); + observerCallback(); + expect(resizeSpy).toHaveBeenCalledTimes(1); + await sleep(100); + expect(resizeSpy).toHaveBeenCalledTimes(2); + }); +}); diff --git a/packages/map/__tests__/map/map_world_copies.spec.ts b/packages/map/__tests__/map/map_world_copies.spec.ts new file mode 100644 index 00000000000..5722e56a871 --- /dev/null +++ b/packages/map/__tests__/map/map_world_copies.spec.ts @@ -0,0 +1,101 @@ +import { beforeMapTest, createMap } from '../libs/util'; + +beforeEach(() => { + beforeMapTest(); + global.fetch = null; +}); + +describe('#getRenderWorldCopies', () => { + test('initially false', () => { + const map = createMap({ renderWorldCopies: false }); + expect(map.getRenderWorldCopies()).toBe(false); + }); + + test('initially true', () => { + const map = createMap({ renderWorldCopies: true }); + expect(map.getRenderWorldCopies()).toBe(true); + }); +}); + +describe('#setRenderWorldCopies', () => { + test('initially false', () => { + const map = createMap({ renderWorldCopies: false }); + map.setRenderWorldCopies(true); + expect(map.getRenderWorldCopies()).toBe(true); + }); + + test('initially true', () => { + const map = createMap({ renderWorldCopies: true }); + map.setRenderWorldCopies(false); + expect(map.getRenderWorldCopies()).toBe(false); + }); + + test('undefined', () => { + const map = createMap({ renderWorldCopies: false }); + map.setRenderWorldCopies(undefined); + expect(map.getRenderWorldCopies()).toBe(true); + }); + + test('null', () => { + const map = createMap({ renderWorldCopies: true }); + map.setRenderWorldCopies(null); + expect(map.getRenderWorldCopies()).toBe(false); + }); +}); + +describe('#renderWorldCopies', () => { + test('does not constrain horizontal panning when renderWorldCopies is set to true', () => { + const map = createMap({ renderWorldCopies: true }); + map.setCenter({ lng: 180, lat: 0 }); + expect(map.getCenter().lng).toBe(180); + }); + + test('constrains horizontal panning when renderWorldCopies is set to false', () => { + const map = createMap({ renderWorldCopies: false }); + map.setCenter({ lng: 180, lat: 0 }); + expect(map.getCenter().lng).toBeCloseTo(110, 0); + }); + + test('does not wrap the map when renderWorldCopies is set to false', () => { + const map = createMap({ renderWorldCopies: false }); + map.setCenter({ lng: 200, lat: 0 }); + expect(map.getCenter().lng).toBeCloseTo(110, 0); + }); + + test('panTo is constrained to single globe when renderWorldCopies is set to false', () => { + const map = createMap({ renderWorldCopies: false }); + map.panTo({ lng: 180, lat: 0 }, { duration: 0 }); + expect(map.getCenter().lng).toBeCloseTo(110, 0); + map.panTo({ lng: -3000, lat: 0 }, { duration: 0 }); + expect(map.getCenter().lng).toBeCloseTo(-110, 0); + }); + + test('flyTo is constrained to single globe when renderWorldCopies is set to false', () => { + const map = createMap({ renderWorldCopies: false }); + map.flyTo({ center: [1000, 0], zoom: 3, animate: false }); + expect(map.getCenter().lng).toBeCloseTo(171, 0); + map.flyTo({ center: [-1000, 0], zoom: 5, animate: false }); + expect(map.getCenter().lng).toBeCloseTo(-178, 0); + }); + + test('lng is constrained to a single globe when zooming with {renderWorldCopies: false}', () => { + const map = createMap({ renderWorldCopies: false, center: [180, 0], zoom: 2 }); + expect(map.getCenter().lng).toBeCloseTo(162, 0); + map.zoomTo(1, { animate: false }); + expect(map.getCenter().lng).toBeCloseTo(145, 0); + }); + + test('lng is constrained by maxBounds when {renderWorldCopies: false}', () => { + const map = createMap({ + renderWorldCopies: false, + maxBounds: [ + [70, 30], + [80, 40], + ], + zoom: 8, + center: [75, 35], + }); + map.setCenter({ lng: 180, lat: 0 }); + expect(map.getCenter().lng).toBeCloseTo(80, 0); + }); +}); diff --git a/packages/map/__tests__/map/map_zoom.spec.ts b/packages/map/__tests__/map/map_zoom.spec.ts new file mode 100644 index 00000000000..865630eba97 --- /dev/null +++ b/packages/map/__tests__/map/map_zoom.spec.ts @@ -0,0 +1,78 @@ +import { beforeMapTest, createMap } from '../libs/util'; + +beforeEach(() => { + beforeMapTest(); + global.fetch = null; +}); + +test('#setMinZoom', () => { + const map = createMap({ zoom: 5 }); + map.setMinZoom(3.5); + map.setZoom(1); + expect(map.getZoom()).toBe(3.5); +}); + +test('unset minZoom', () => { + const map = createMap({ minZoom: 5 }); + map.setMinZoom(null); + map.setZoom(1); + expect(map.getZoom()).toBe(1); +}); + +test('#getMinZoom', () => { + const map = createMap({ zoom: 0 }); + expect(map.getMinZoom()).toBe(-2); + map.setMinZoom(10); + expect(map.getMinZoom()).toBe(10); +}); + +test('ignore minZooms over maxZoom', () => { + const map = createMap({ zoom: 2, maxZoom: 5 }); + expect(() => { + map.setMinZoom(6); + }).toThrow(); + map.setZoom(0); + expect(map.getZoom()).toBe(0); +}); + +test('#setMaxZoom', () => { + const map = createMap({ zoom: 0 }); + map.setMaxZoom(3.5); + map.setZoom(4); + expect(map.getZoom()).toBe(3.5); +}); + +test('unset maxZoom', () => { + const map = createMap({ maxZoom: 5 }); + map.setMaxZoom(null); + map.setZoom(6); + expect(map.getZoom()).toBe(6); +}); + +test('#getMaxZoom', () => { + const map = createMap({ zoom: 0 }); + expect(map.getMaxZoom()).toBe(22); + map.setMaxZoom(10); + expect(map.getMaxZoom()).toBe(10); +}); + +test('ignore maxZooms over minZoom', () => { + const map = createMap({ minZoom: 5 }); + expect(() => { + map.setMaxZoom(4); + }).toThrow(); + map.setZoom(5); + expect(map.getZoom()).toBe(5); +}); + +test('throw on maxZoom smaller than minZoom at init', () => { + expect(() => { + createMap({ minZoom: 10, maxZoom: 5 }); + }).toThrow(new Error('maxZoom must be greater than or equal to minZoom')); +}); + +test('throw on maxZoom smaller than minZoom at init with falsey maxZoom', () => { + expect(() => { + createMap({ minZoom: 1, maxZoom: 0 }); + }).toThrow(new Error('maxZoom must be greater than or equal to minZoom')); +}); diff --git a/packages/map/__tests__/util/browser.spec.ts b/packages/map/__tests__/util/browser.spec.ts new file mode 100644 index 00000000000..dbc8d7cb2ec --- /dev/null +++ b/packages/map/__tests__/util/browser.spec.ts @@ -0,0 +1,19 @@ +import { browser } from '../../src/map/util/browser'; + +describe('browser', () => { + test('frameAsync', async () => { + const id = await browser.frameAsync(new AbortController()); + expect(id).toBeTruthy(); + }); + + test('now', () => { + expect(typeof browser.now()).toBe('number'); + }); + + test('frameAsync', async () => { + const abortController = new AbortController(); + const promise = browser.frameAsync(abortController); + abortController.abort(); + await expect(promise).rejects.toThrow(); + }); +}); diff --git a/packages/map/__tests__/util/evented.spec.ts b/packages/map/__tests__/util/evented.spec.ts new file mode 100644 index 00000000000..313357fc4de --- /dev/null +++ b/packages/map/__tests__/util/evented.spec.ts @@ -0,0 +1,193 @@ +import { Event, Evented } from '../../src/map/util/evented'; + +describe('Evented', () => { + test('calls listeners added with "on"', () => { + const evented = new Evented(); + const listener = jest.fn(); + evented.on('a', listener); + evented.fire(new Event('a')); + evented.fire(new Event('a')); + expect(listener).toHaveBeenCalledTimes(2); + }); + + test('calls listeners added with "once" once', () => { + const evented = new Evented(); + const listener = jest.fn(); + evented.once('a', listener); + evented.fire(new Event('a')); + evented.fire(new Event('a')); + expect(listener).toHaveBeenCalledTimes(1); + expect(evented.listens('a')).toBeFalsy(); + }); + + test('returns a promise when no listener is provided to "once" method', async () => { + const evented = new Evented(); + const promise = evented.once('a'); + evented.fire(new Event('a')); + evented.fire(new Event('a')); + await promise; + expect(evented.listens('a')).toBeFalsy(); + }); + + test('passes data to listeners', () => { + const evented = new Evented(); + evented.on('a', (data) => { + expect(data.foo).toBe('bar'); + }); + evented.fire(new Event('a', { foo: 'bar' })); + }); + + test('passes "target" to listeners', () => { + const evented = new Evented(); + evented.on('a', (data) => { + expect(data.target).toBe(evented); + }); + evented.fire(new Event('a')); + }); + + test('passes "type" to listeners', () => { + const evented = new Evented(); + evented.on('a', (data) => { + expect(data.type).toBe('a'); + }); + evented.fire(new Event('a')); + }); + + test('removes listeners with "off"', () => { + const evented = new Evented(); + const listener = jest.fn(); + evented.on('a', listener); + evented.off('a', listener); + evented.fire(new Event('a')); + expect(listener).not.toHaveBeenCalled(); + }); + + test('removes one-time listeners with "off"', () => { + const evented = new Evented(); + const listener = jest.fn(); + evented.once('a', listener); + evented.off('a', listener); + evented.fire(new Event('a')); + expect(listener).not.toHaveBeenCalled(); + }); + + test('once listener is removed prior to call', () => { + const evented = new Evented(); + const listener = jest.fn(); + evented.once('a', () => { + listener(); + evented.fire(new Event('a')); + }); + evented.fire(new Event('a')); + expect(listener).toHaveBeenCalledTimes(1); + }); + + test('reports if an event has listeners with "listens"', () => { + const evented = new Evented(); + evented.on('a', () => {}); + expect(evented.listens('a')).toBeTruthy(); + expect(evented.listens('b')).toBeFalsy(); + }); + + test('does not report true to "listens" if all listeners have been removed', () => { + const evented = new Evented(); + const listener = () => {}; + evented.on('a', listener); + evented.off('a', listener); + expect(evented.listens('a')).toBeFalsy(); + }); + + test('does not immediately call listeners added within another listener', (done) => { + const evented = new Evented(); + evented.on('a', () => { + evented.on('a', () => done('fail')); + }); + evented.fire(new Event('a')); + done(); + }); + + test('has backward compatibility for fire(string, object) API', () => { + const evented = new Evented(); + const listener = jest.fn((x) => x); + evented.on('a', listener); + evented.fire('a' as any as Event, { foo: 'bar' }); + expect(listener).toHaveBeenCalledTimes(1); + expect(listener.mock.calls[0][0].foo).toBe('bar'); + }); + + test('on is idempotent', () => { + const evented = new Evented(); + const order: string[] = []; + const listenerA = jest.fn(() => order.push('A')); + const listenerB = jest.fn(() => order.push('B')); + evented.on('a', listenerA); + evented.on('a', listenerB); + evented.on('a', listenerA); + evented.fire(new Event('a')); + expect(listenerA).toHaveBeenCalledTimes(1); + expect(order).toEqual(['A', 'B']); + }); +}); + +describe('evented parents', () => { + test('adds parents with "setEventedParent"', () => { + const listener = jest.fn(); + const eventedSource = new Evented(); + const eventedSink = new Evented(); + eventedSource.setEventedParent(eventedSink); + eventedSink.on('a', listener); + eventedSource.fire(new Event('a')); + eventedSource.fire(new Event('a')); + expect(listener).toHaveBeenCalledTimes(2); + }); + + test('passes original data to parent listeners', () => { + const eventedSource = new Evented(); + const eventedSink = new Evented(); + eventedSource.setEventedParent(eventedSink); + eventedSink.on('a', (data) => { + expect(data.foo).toBe('bar'); + }); + eventedSource.fire(new Event('a', { foo: 'bar' })); + }); + + test('attaches parent data to parent listeners', () => { + const eventedSource = new Evented(); + const eventedSink = new Evented(); + eventedSource.setEventedParent(eventedSink, { foz: 'baz' }); + eventedSink.on('a', (data) => { + expect(data.foz).toBe('baz'); + }); + eventedSource.fire(new Event('a', { foo: 'bar' })); + }); + + test('attaches parent data from a function to parent listeners', () => { + const eventedSource = new Evented(); + const eventedSink = new Evented(); + eventedSource.setEventedParent(eventedSink, () => ({ foz: 'baz' })); + eventedSink.on('a', (data) => { + expect(data.foz).toBe('baz'); + }); + eventedSource.fire(new Event('a', { foo: 'bar' })); + }); + + test('reports if an event has parent listeners with "listens"', () => { + const eventedSource = new Evented(); + const eventedSink = new Evented(); + eventedSink.on('a', () => {}); + eventedSource.setEventedParent(eventedSink); + expect(eventedSink.listens('a')).toBeTruthy(); + }); + + test('eventedParent data function is evaluated on every fire', () => { + const eventedSource = new Evented(); + const eventedParent = new Evented(); + let i = 0; + eventedSource.setEventedParent(eventedParent, () => i++); + eventedSource.on('a', () => {}); + eventedSource.fire(new Event('a')); + expect(i).toBe(1); + eventedSource.fire(new Event('a')); + expect(i).toBe(2); + }); +}); diff --git a/packages/map/__tests__/util/task_queue.spec.ts b/packages/map/__tests__/util/task_queue.spec.ts new file mode 100644 index 00000000000..054688ef4b8 --- /dev/null +++ b/packages/map/__tests__/util/task_queue.spec.ts @@ -0,0 +1,114 @@ +import { TaskQueue } from '../../src/map/util/task_queue'; + +describe('TaskQueue', () => { + test('Calls callbacks, in order', () => { + const q = new TaskQueue(); + let first = 0; + let second = 0; + q.add(() => { + expect(++first).toBe(1); + expect(second).toBe(0); + }); + q.add(() => { + expect(first).toBe(1); + expect(++second).toBe(1); + }); + q.run(); + expect(first).toBe(1); + expect(second).toBe(1); + }); + + test('Allows a given callback to be queued multiple times', () => { + const q = new TaskQueue(); + const fn = jest.fn(); + q.add(fn); + q.add(fn); + q.run(); + expect(fn).toHaveBeenCalledTimes(2); + }); + + test('Does not call a callback that was cancelled before the queue was run', () => { + const q = new TaskQueue(); + const yes = jest.fn(); + const no = jest.fn(); + q.add(yes); + const id = q.add(no); + q.remove(id); + q.run(); + expect(yes).toHaveBeenCalledTimes(1); + expect(no).not.toHaveBeenCalled(); + }); + + test('Does not call a callback that was cancelled while the queue was running', () => { + const q = new TaskQueue(); + const yes = jest.fn(); + const no = jest.fn(); + q.add(yes); + let id; // eslint-disable-line prefer-const + q.add(() => q.remove(id)); + id = q.add(no); + q.run(); + expect(yes).toHaveBeenCalledTimes(1); + expect(no).not.toHaveBeenCalled(); + }); + + test('Allows each instance of a multiply-queued callback to be cancelled independently', () => { + const q = new TaskQueue(); + const cb = jest.fn(); + q.add(cb); + const id = q.add(cb); + q.remove(id); + q.run(); + expect(cb).toHaveBeenCalledTimes(1); + }); + + test('Does not throw if a remove() is called after running the queue', () => { + const q = new TaskQueue(); + const cb = jest.fn(); + const id = q.add(cb); + q.run(); + q.remove(id); + expect(cb).toHaveBeenCalledTimes(1); + }); + + test('Does not add tasks to the currently-running queue', () => { + const q = new TaskQueue(); + const cb = jest.fn(); + q.add(() => q.add(cb)); + q.run(); + expect(cb).not.toHaveBeenCalled(); + q.run(); + expect(cb).toHaveBeenCalledTimes(1); + }); + + test('TaskQueue#run() throws on attempted re-entrance', () => { + const q = new TaskQueue(); + q.add(() => q.run()); + expect(() => q.run()).toThrow(); + }); + + test('TaskQueue#clear() prevents queued task from being executed', () => { + const q = new TaskQueue(); + const before = jest.fn(); + const after = jest.fn(); + q.add(before); + q.clear(); + q.add(after); + q.run(); + expect(before).not.toHaveBeenCalled(); + expect(after).toHaveBeenCalledTimes(1); + }); + + test('TaskQueue#clear() interrupts currently-running queue', () => { + const q = new TaskQueue(); + const before = jest.fn(); + const after = jest.fn(); + q.add(() => q.add(after)); + q.add(() => q.clear()); + q.add(before); + q.run(); + expect(before).not.toHaveBeenCalled(); + q.run(); + expect(after).not.toHaveBeenCalled(); + }); +}); diff --git a/packages/map/legacy/README.md b/packages/map/legacy/README.md new file mode 100644 index 00000000000..26b480e6f50 --- /dev/null +++ b/packages/map/legacy/README.md @@ -0,0 +1,3 @@ +## Map + +Map fork from [mapbox-gl-js@1.x](https://github.com/mapbox/mapbox-gl-js/tree/release-v1.13.3), keep event loop, responds user interaction and updates the internal state of the map (current viewport, camera angle, etc.) diff --git a/packages/map/src/camera.ts b/packages/map/legacy/camera.ts similarity index 100% rename from packages/map/src/camera.ts rename to packages/map/legacy/camera.ts diff --git a/packages/map/src/css/l7.css b/packages/map/legacy/css/l7.css similarity index 71% rename from packages/map/src/css/l7.css rename to packages/map/legacy/css/l7.css index f1faa047a3f..4a6d99c3970 100644 --- a/packages/map/src/css/l7.css +++ b/packages/map/legacy/css/l7.css @@ -26,12 +26,7 @@ .l7-canvas-container.l7-interactive, .l7-ctrl-group button.l7-ctrl-compass { - cursor: -webkit-grab; - cursor: -moz-grab; cursor: grab; - -moz-user-select: none; - -webkit-user-select: none; - -ms-user-select: none; user-select: none; } @@ -41,8 +36,6 @@ .l7-canvas-container.l7-interactive:active, .l7-ctrl-group button.l7-ctrl-compass:active { - cursor: -webkit-grabbing; - cursor: -moz-grabbing; cursor: grabbing; } @@ -61,6 +54,47 @@ touch-action: none; } +.l7-canvas-container.l7-touch-drag-pan.l7-cooperative-gestures, +.l7-canvas-container.l7-touch-drag-pan.l7-cooperative-gestures .l7-canvas { + touch-action: pan-x pan-y; +} + +.l7-cooperative-gesture-screen { + background: rgba(0 0 0 / 40%); + position: absolute; + inset: 0; + display: flex; + justify-content: center; + align-items: center; + color: white; + padding: 1rem; + font-size: 1.4em; + line-height: 1.2; + opacity: 0; + pointer-events: none; + transition: opacity 1s ease 1s; + z-index: 99999; +} + +.l7-cooperative-gesture-screen.l7-show { + opacity: 1; + transition: opacity 0.05s; +} + +.l7-cooperative-gesture-screen .l7-mobile-message { + display: none; +} + +@media (hover: none), (width <= 480px) { + .l7-cooperative-gesture-screen .l7-desktop-message { + display: none; + } + + .l7-cooperative-gesture-screen .l7-mobile-message { + display: block; + } +} + .l7-ctrl-top-left, .l7-ctrl-top-right, .l7-ctrl-bottom-left, diff --git a/packages/map/src/earthmap.ts b/packages/map/legacy/earthmap.ts similarity index 99% rename from packages/map/src/earthmap.ts rename to packages/map/legacy/earthmap.ts index de95de44546..185a7b9749f 100644 --- a/packages/map/src/earthmap.ts +++ b/packages/map/legacy/earthmap.ts @@ -58,6 +58,10 @@ const DefaultOptions: IMapOptions = { pitchEnabled: true, rotateEnabled: true, }; + +/** + * @deprecated + */ export class EarthMap extends Camera { public doubleClickZoom: DoubleClickZoomHandler; public dragRotate: DragRotateHandler; diff --git a/packages/map/src/geo/edge_insets.ts b/packages/map/legacy/geo/edge_insets.ts similarity index 100% rename from packages/map/src/geo/edge_insets.ts rename to packages/map/legacy/geo/edge_insets.ts diff --git a/packages/map/src/geo/lng_lat.ts b/packages/map/legacy/geo/lng_lat.ts similarity index 100% rename from packages/map/src/geo/lng_lat.ts rename to packages/map/legacy/geo/lng_lat.ts diff --git a/packages/map/src/geo/lng_lat_bounds.ts b/packages/map/legacy/geo/lng_lat_bounds.ts similarity index 100% rename from packages/map/src/geo/lng_lat_bounds.ts rename to packages/map/legacy/geo/lng_lat_bounds.ts diff --git a/packages/map/src/geo/mercator.ts b/packages/map/legacy/geo/mercator.ts similarity index 95% rename from packages/map/src/geo/mercator.ts rename to packages/map/legacy/geo/mercator.ts index b8eb9347c00..dcee92f63fe 100644 --- a/packages/map/src/geo/mercator.ts +++ b/packages/map/legacy/geo/mercator.ts @@ -1,5 +1,5 @@ -import type { LngLatLike } from '../geo/lng_lat'; -import LngLat, { earthRadius } from '../geo/lng_lat'; +import type { LngLatLike } from './lng_lat'; +import LngLat, { earthRadius } from './lng_lat'; /* * The average circumference of the world in meters. diff --git a/packages/map/src/geo/point.ts b/packages/map/legacy/geo/point.ts similarity index 100% rename from packages/map/src/geo/point.ts rename to packages/map/legacy/geo/point.ts diff --git a/packages/map/src/geo/simple.ts b/packages/map/legacy/geo/simple.ts similarity index 95% rename from packages/map/src/geo/simple.ts rename to packages/map/legacy/geo/simple.ts index 7219394d437..24cbc9ea735 100644 --- a/packages/map/src/geo/simple.ts +++ b/packages/map/legacy/geo/simple.ts @@ -1,5 +1,5 @@ -import type { LngLatLike } from '../geo/lng_lat'; -import LngLat, { earthRadius } from '../geo/lng_lat'; +import type { LngLatLike } from './lng_lat'; +import LngLat, { earthRadius } from './lng_lat'; /* * The average circumference of the world in meters. diff --git a/packages/map/src/geo/transform.ts b/packages/map/legacy/geo/transform.ts similarity index 99% rename from packages/map/src/geo/transform.ts rename to packages/map/legacy/geo/transform.ts index db33c0f83e4..8505ec8e0ec 100644 --- a/packages/map/src/geo/transform.ts +++ b/packages/map/legacy/geo/transform.ts @@ -1,6 +1,5 @@ // @ts-ignore import { mat2, mat4, vec4 } from 'gl-matrix'; -import Point from '../geo/point'; import { clamp, interpolate, wrap } from '../util'; import type { IPaddingOptions } from './edge_insets'; import EdgeInsets from './edge_insets'; @@ -11,6 +10,7 @@ import MercatorCoordinate, { mercatorYfromLat, mercatorZfromAltitude, } from './mercator'; +import Point from './point'; export const EXTENT = 8192; export default class Transform { get minZoom(): number { diff --git a/packages/map/src/handler/IHandler.ts b/packages/map/legacy/handler/IHandler.ts similarity index 100% rename from packages/map/src/handler/IHandler.ts rename to packages/map/legacy/handler/IHandler.ts diff --git a/packages/map/src/handler/blockable_map_event.ts b/packages/map/legacy/handler/blockable_map_event.ts similarity index 100% rename from packages/map/src/handler/blockable_map_event.ts rename to packages/map/legacy/handler/blockable_map_event.ts diff --git a/packages/map/src/handler/box_zoom.ts b/packages/map/legacy/handler/box_zoom.ts similarity index 100% rename from packages/map/src/handler/box_zoom.ts rename to packages/map/legacy/handler/box_zoom.ts diff --git a/packages/map/src/handler/click_zoom.ts b/packages/map/legacy/handler/click_zoom.ts similarity index 100% rename from packages/map/src/handler/click_zoom.ts rename to packages/map/legacy/handler/click_zoom.ts diff --git a/packages/map/src/handler/events/event.ts b/packages/map/legacy/handler/events/event.ts similarity index 100% rename from packages/map/src/handler/events/event.ts rename to packages/map/legacy/handler/events/event.ts diff --git a/packages/map/src/handler/events/index.ts b/packages/map/legacy/handler/events/index.ts similarity index 100% rename from packages/map/src/handler/events/index.ts rename to packages/map/legacy/handler/events/index.ts diff --git a/packages/map/src/handler/events/map_mouse_event.ts b/packages/map/legacy/handler/events/map_mouse_event.ts similarity index 100% rename from packages/map/src/handler/events/map_mouse_event.ts rename to packages/map/legacy/handler/events/map_mouse_event.ts diff --git a/packages/map/src/handler/events/map_touch_event.ts b/packages/map/legacy/handler/events/map_touch_event.ts similarity index 100% rename from packages/map/src/handler/events/map_touch_event.ts rename to packages/map/legacy/handler/events/map_touch_event.ts diff --git a/packages/map/src/handler/events/map_wheel_event.ts b/packages/map/legacy/handler/events/map_wheel_event.ts similarity index 100% rename from packages/map/src/handler/events/map_wheel_event.ts rename to packages/map/legacy/handler/events/map_wheel_event.ts diff --git a/packages/map/src/handler/events/render_event.ts b/packages/map/legacy/handler/events/render_event.ts similarity index 100% rename from packages/map/src/handler/events/render_event.ts rename to packages/map/legacy/handler/events/render_event.ts diff --git a/packages/map/src/handler/handler_inertia.ts b/packages/map/legacy/handler/handler_inertia.ts similarity index 100% rename from packages/map/src/handler/handler_inertia.ts rename to packages/map/legacy/handler/handler_inertia.ts diff --git a/packages/map/src/handler/handler_manager.ts b/packages/map/legacy/handler/handler_manager.ts similarity index 100% rename from packages/map/src/handler/handler_manager.ts rename to packages/map/legacy/handler/handler_manager.ts diff --git a/packages/map/src/handler/handler_util.ts b/packages/map/legacy/handler/handler_util.ts similarity index 100% rename from packages/map/src/handler/handler_util.ts rename to packages/map/legacy/handler/handler_util.ts diff --git a/packages/map/src/handler/keyboard.ts b/packages/map/legacy/handler/keyboard.ts similarity index 100% rename from packages/map/src/handler/keyboard.ts rename to packages/map/legacy/handler/keyboard.ts diff --git a/packages/map/src/handler/map_event.ts b/packages/map/legacy/handler/map_event.ts similarity index 100% rename from packages/map/src/handler/map_event.ts rename to packages/map/legacy/handler/map_event.ts diff --git a/packages/map/src/handler/mouse/index.ts b/packages/map/legacy/handler/mouse/index.ts similarity index 100% rename from packages/map/src/handler/mouse/index.ts rename to packages/map/legacy/handler/mouse/index.ts diff --git a/packages/map/src/handler/mouse/mouse_handler.ts b/packages/map/legacy/handler/mouse/mouse_handler.ts similarity index 100% rename from packages/map/src/handler/mouse/mouse_handler.ts rename to packages/map/legacy/handler/mouse/mouse_handler.ts diff --git a/packages/map/src/handler/mouse/mousepan_handler.ts b/packages/map/legacy/handler/mouse/mousepan_handler.ts similarity index 100% rename from packages/map/src/handler/mouse/mousepan_handler.ts rename to packages/map/legacy/handler/mouse/mousepan_handler.ts diff --git a/packages/map/src/handler/mouse/mousepitch_hander.ts b/packages/map/legacy/handler/mouse/mousepitch_hander.ts similarity index 100% rename from packages/map/src/handler/mouse/mousepitch_hander.ts rename to packages/map/legacy/handler/mouse/mousepitch_hander.ts diff --git a/packages/map/src/handler/mouse/mouserotate_hander.ts b/packages/map/legacy/handler/mouse/mouserotate_hander.ts similarity index 100% rename from packages/map/src/handler/mouse/mouserotate_hander.ts rename to packages/map/legacy/handler/mouse/mouserotate_hander.ts diff --git a/packages/map/src/handler/mouse/util.ts b/packages/map/legacy/handler/mouse/util.ts similarity index 100% rename from packages/map/src/handler/mouse/util.ts rename to packages/map/legacy/handler/mouse/util.ts diff --git a/packages/map/src/handler/scroll_zoom.ts b/packages/map/legacy/handler/scroll_zoom.ts similarity index 100% rename from packages/map/src/handler/scroll_zoom.ts rename to packages/map/legacy/handler/scroll_zoom.ts diff --git a/packages/map/src/handler/shim/dblclick_zoom.ts b/packages/map/legacy/handler/shim/dblclick_zoom.ts similarity index 100% rename from packages/map/src/handler/shim/dblclick_zoom.ts rename to packages/map/legacy/handler/shim/dblclick_zoom.ts diff --git a/packages/map/src/handler/shim/drag_pan.ts b/packages/map/legacy/handler/shim/drag_pan.ts similarity index 95% rename from packages/map/src/handler/shim/drag_pan.ts rename to packages/map/legacy/handler/shim/drag_pan.ts index 751121dbbec..8b734189608 100644 --- a/packages/map/src/handler/shim/drag_pan.ts +++ b/packages/map/legacy/handler/shim/drag_pan.ts @@ -1,5 +1,5 @@ -import type { MousePanHandler } from '../mouse/'; -import type { TouchPanHandler } from '../touch/'; +import type { MousePanHandler } from '../mouse'; +import type { TouchPanHandler } from '../touch'; export interface IDragPanOptions { linearity?: number; diff --git a/packages/map/src/handler/shim/drag_rotate.ts b/packages/map/legacy/handler/shim/drag_rotate.ts similarity index 100% rename from packages/map/src/handler/shim/drag_rotate.ts rename to packages/map/legacy/handler/shim/drag_rotate.ts diff --git a/packages/map/src/handler/shim/touch_zoom_rotate.ts b/packages/map/legacy/handler/shim/touch_zoom_rotate.ts similarity index 100% rename from packages/map/src/handler/shim/touch_zoom_rotate.ts rename to packages/map/legacy/handler/shim/touch_zoom_rotate.ts diff --git a/packages/map/src/handler/tap/single_tap_recognizer.ts b/packages/map/legacy/handler/tap/single_tap_recognizer.ts similarity index 100% rename from packages/map/src/handler/tap/single_tap_recognizer.ts rename to packages/map/legacy/handler/tap/single_tap_recognizer.ts diff --git a/packages/map/src/handler/tap/tap_drag_zoom.ts b/packages/map/legacy/handler/tap/tap_drag_zoom.ts similarity index 100% rename from packages/map/src/handler/tap/tap_drag_zoom.ts rename to packages/map/legacy/handler/tap/tap_drag_zoom.ts diff --git a/packages/map/src/handler/tap/tap_recognizer.ts b/packages/map/legacy/handler/tap/tap_recognizer.ts similarity index 100% rename from packages/map/src/handler/tap/tap_recognizer.ts rename to packages/map/legacy/handler/tap/tap_recognizer.ts diff --git a/packages/map/src/handler/tap/tap_zoom.ts b/packages/map/legacy/handler/tap/tap_zoom.ts similarity index 100% rename from packages/map/src/handler/tap/tap_zoom.ts rename to packages/map/legacy/handler/tap/tap_zoom.ts diff --git a/packages/map/src/handler/touch/index.ts b/packages/map/legacy/handler/touch/index.ts similarity index 100% rename from packages/map/src/handler/touch/index.ts rename to packages/map/legacy/handler/touch/index.ts diff --git a/packages/map/src/handler/touch/touch_pan.ts b/packages/map/legacy/handler/touch/touch_pan.ts similarity index 100% rename from packages/map/src/handler/touch/touch_pan.ts rename to packages/map/legacy/handler/touch/touch_pan.ts diff --git a/packages/map/src/handler/touch/touch_pitch.ts b/packages/map/legacy/handler/touch/touch_pitch.ts similarity index 100% rename from packages/map/src/handler/touch/touch_pitch.ts rename to packages/map/legacy/handler/touch/touch_pitch.ts diff --git a/packages/map/src/handler/touch/touch_rotate.ts b/packages/map/legacy/handler/touch/touch_rotate.ts similarity index 100% rename from packages/map/src/handler/touch/touch_rotate.ts rename to packages/map/legacy/handler/touch/touch_rotate.ts diff --git a/packages/map/src/handler/touch/touch_zoom.ts b/packages/map/legacy/handler/touch/touch_zoom.ts similarity index 100% rename from packages/map/src/handler/touch/touch_zoom.ts rename to packages/map/legacy/handler/touch/touch_zoom.ts diff --git a/packages/map/src/handler/touch/two_touch.ts b/packages/map/legacy/handler/touch/two_touch.ts similarity index 100% rename from packages/map/src/handler/touch/two_touch.ts rename to packages/map/legacy/handler/touch/two_touch.ts diff --git a/packages/map/src/hash.ts b/packages/map/legacy/hash.ts similarity index 100% rename from packages/map/src/hash.ts rename to packages/map/legacy/hash.ts diff --git a/packages/map/src/interface.ts b/packages/map/legacy/interface.ts similarity index 94% rename from packages/map/src/interface.ts rename to packages/map/legacy/interface.ts index a33eb93060f..fe668a43f72 100644 --- a/packages/map/src/interface.ts +++ b/packages/map/legacy/interface.ts @@ -1,5 +1,9 @@ import type { LngLatBoundsLike } from './geo/lng_lat_bounds'; +/** + * @deprecated + * 请使用 MapOptions + */ export interface IMapOptions { hash: boolean; style?: any; diff --git a/packages/map/src/map.ts b/packages/map/legacy/map.ts similarity index 99% rename from packages/map/src/map.ts rename to packages/map/legacy/map.ts index ec6c7d7f2aa..b363fc24b01 100644 --- a/packages/map/src/map.ts +++ b/packages/map/legacy/map.ts @@ -1,6 +1,6 @@ import { DOM, lodashUtil } from '@antv/l7-utils'; import Camera from './camera'; -import './css/l7.css'; +// import './css/l7.css'; import type { LngLatLike } from './geo/lng_lat'; import LngLat from './geo/lng_lat'; import type { LngLatBoundsLike } from './geo/lng_lat_bounds'; @@ -74,6 +74,10 @@ const DefaultOptions: IMapOptions = { pitchEnabled: true, rotateEnabled: true, }; + +/** + * @deprecated + */ export class Map extends Camera { public doubleClickZoom: DoubleClickZoomHandler; public dragRotate: DragRotateHandler; diff --git a/packages/map/src/util.ts b/packages/map/legacy/util.ts similarity index 100% rename from packages/map/src/util.ts rename to packages/map/legacy/util.ts diff --git a/packages/map/src/utils/Aabb.ts b/packages/map/legacy/utils/Aabb.ts similarity index 100% rename from packages/map/src/utils/Aabb.ts rename to packages/map/legacy/utils/Aabb.ts diff --git a/packages/map/src/utils/dom.ts b/packages/map/legacy/utils/dom.ts similarity index 100% rename from packages/map/src/utils/dom.ts rename to packages/map/legacy/utils/dom.ts diff --git a/packages/map/src/utils/performance.ts b/packages/map/legacy/utils/performance.ts similarity index 100% rename from packages/map/src/utils/performance.ts rename to packages/map/legacy/utils/performance.ts diff --git a/packages/map/src/utils/primitives.ts b/packages/map/legacy/utils/primitives.ts similarity index 100% rename from packages/map/src/utils/primitives.ts rename to packages/map/legacy/utils/primitives.ts diff --git a/packages/map/src/utils/task_queue.ts b/packages/map/legacy/utils/task_queue.ts similarity index 100% rename from packages/map/src/utils/task_queue.ts rename to packages/map/legacy/utils/task_queue.ts diff --git a/packages/map/package.json b/packages/map/package.json index 3244422aadd..c4b3b467fbd 100644 --- a/packages/map/package.json +++ b/packages/map/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7-map", - "version": "2.21.10", + "version": "2.21.11-beta.7", "description": "L7 Map", "keywords": [], "homepage": "https://github.com/antvis/L7#readme", @@ -32,10 +32,13 @@ "@antv/l7-utils": "workspace:*", "@babel/runtime": "^7.7.7", "@mapbox/point-geometry": "^0.1.0", - "@mapbox/unitbezier": "^0.0.0", + "@mapbox/unitbezier": "^0.0.1", "eventemitter3": "^4.0.4", "gl-matrix": "^3.1.0" }, + "devDependencies": { + "@types/mapbox__point-geometry": "^0.1.4" + }, "publishConfig": { "access": "public", "registry": "https://registry.npmjs.org" diff --git a/packages/map/src/index.ts b/packages/map/src/index.ts index 25c19e47d52..17cccc0d849 100644 --- a/packages/map/src/index.ts +++ b/packages/map/src/index.ts @@ -1,4 +1,3 @@ -export * from './earthmap'; -export * from './geo/mercator'; -export * from './interface'; -export * from './map'; +export { MercatorCoordinate } from './map/geo/mercator_coordinate'; +export { Map } from './map/map'; +export type { MapOptions } from './map/map'; diff --git a/packages/map/src/map/camera.ts b/packages/map/src/map/camera.ts new file mode 100644 index 00000000000..b0301c51b7a --- /dev/null +++ b/packages/map/src/map/camera.ts @@ -0,0 +1,1503 @@ +import Point from '@mapbox/point-geometry'; +import { LngLat } from './geo/lng_lat'; +import { LngLatBounds } from './geo/lng_lat_bounds'; +import { MercatorCoordinate } from './geo/mercator_coordinate'; +import { browser } from './util/browser'; +import { Event, Evented } from './util/evented'; +import { + clamp, + defaultEasing, + degreesToRadians, + extend, + interpolates, + pick, + warnOnce, + wrap, +} from './util/util'; + +import type { PaddingOptions } from './geo/edge_insets'; +import type { LngLatLike } from './geo/lng_lat'; +import type { LngLatBoundsLike } from './geo/lng_lat_bounds'; +import type { Transform } from './geo/transform'; +import type { HandlerManager } from './handler_manager'; +import type { TaskID } from './util/task_queue'; +/** + * A [Point](https://github.com/mapbox/point-geometry) or an array of two numbers representing `x` and `y` screen coordinates in pixels. + * + * @group Geography and Geometry + * + * @example + * ```ts + * let p1 = new Point(-77, 38); // a PointLike which is a Point + * let p2 = [-77, 38]; // a PointLike which is an array of two numbers + * ``` + */ +export type PointLike = Point | [number, number]; + +/** + * A helper to allow require of at least one property + */ +export type RequireAtLeastOne = { + [K in keyof T]-?: Required> & Partial>>; +}[keyof T]; + +/** + * Options common to {@link Map#jumpTo}, {@link Map#easeTo}, and {@link Map#flyTo}, controlling the desired location, + * zoom, bearing, and pitch of the camera. All properties are optional, and when a property is omitted, the current + * camera value for that property will remain unchanged. + * + * @example + * Set the map's initial perspective with CameraOptions + * ```ts + * let map = new Map({ + * container: 'map', + * style: 'https://demotiles.maplibre.org/style.json', + * center: [-73.5804, 45.53483], + * pitch: 60, + * bearing: -60, + * zoom: 10 + * }); + * ``` + * @see [Set pitch and bearing](https://maplibre.org/maplibre-gl-js/docs/examples/set-perspective/) + * @see [Jump to a series of locations](https://maplibre.org/maplibre-gl-js/docs/examples/jump-to/) + * @see [Fly to a location](https://maplibre.org/maplibre-gl-js/docs/examples/flyto/) + * @see [Display buildings in 3D](https://maplibre.org/maplibre-gl-js/docs/examples/3d-buildings/) + */ +export type CameraOptions = CenterZoomBearing & { + /** + * The desired pitch in degrees. The pitch is the angle towards the horizon + * measured in degrees with a range between 0 and 60 degrees. For example, pitch: 0 provides the appearance + * of looking straight down at the map, while pitch: 60 tilts the user's perspective towards the horizon. + * Increasing the pitch value is often used to display 3D objects. + */ + pitch?: number; + /** + * If `zoom` is specified, `around` determines the point around which the zoom is centered. + */ + around?: LngLatLike; +}; + +/** + * Holds center, zoom and bearing properties + */ +export type CenterZoomBearing = { + /** + * The desired center. + */ + center?: LngLatLike; + /** + * The desired zoom level. + */ + zoom?: number; + /** + * The desired bearing in degrees. The bearing is the compass direction that + * is "up". For example, `bearing: 90` orients the map so that east is up. + */ + bearing?: number; +}; + +/** + * The options object related to the {@link Map#jumpTo} method + */ +export type JumpToOptions = CameraOptions & { + /** + * Dimensions in pixels applied on each side of the viewport for shifting the vanishing point. + */ + padding?: PaddingOptions; +}; + +/** + * A options object for the {@link Map#cameraForBounds} method + */ +export type CameraForBoundsOptions = CameraOptions & { + /** + * The amount of padding in pixels to add to the given bounds. + */ + padding?: number | RequireAtLeastOne; + /** + * The center of the given bounds relative to the map's center, measured in pixels. + * @defaultValue [0, 0] + */ + offset?: PointLike; + /** + * The maximum zoom level to allow when the camera would transition to the specified bounds. + */ + maxZoom?: number; +}; + +/** + * The {@link Map#flyTo} options object + */ +export type FlyToOptions = AnimationOptions & + CameraOptions & { + /** + * The zooming "curve" that will occur along the + * flight path. A high value maximizes zooming for an exaggerated animation, while a low + * value minimizes zooming for an effect closer to {@link Map#easeTo}. 1.42 is the average + * value selected by participants in the user study discussed in + * [van Wijk (2003)](https://www.win.tue.nl/~vanwijk/zoompan.pdf). A value of + * `Math.pow(6, 0.25)` would be equivalent to the root mean squared average velocity. A + * value of 1 would produce a circular motion. + * @defaultValue 1.42 + */ + curve?: number; + /** + * The zero-based zoom level at the peak of the flight path. If + * `options.curve` is specified, this option is ignored. + */ + minZoom?: number; + /** + * The average speed of the animation defined in relation to + * `options.curve`. A speed of 1.2 means that the map appears to move along the flight path + * by 1.2 times `options.curve` screenfuls every second. A _screenful_ is the map's visible span. + * It does not correspond to a fixed physical distance, but varies by zoom level. + * @defaultValue 1.2 + */ + speed?: number; + /** + * The average speed of the animation measured in screenfuls + * per second, assuming a linear timing curve. If `options.speed` is specified, this option is ignored. + */ + screenSpeed?: number; + /** + * The animation's maximum duration, measured in milliseconds. + * If duration exceeds maximum duration, it resets to 0. + */ + maxDuration?: number; + /** + * The amount of padding in pixels to add to the given bounds. + */ + padding?: number | RequireAtLeastOne; + }; + +export type EaseToOptions = AnimationOptions & + CameraOptions & { + delayEndEvents?: number; + padding?: number | RequireAtLeastOne; + }; + +/** + * Options for {@link Map#fitBounds} method + */ +export type FitBoundsOptions = FlyToOptions & { + /** + * If `true`, the map transitions using {@link Map#easeTo}. If `false`, the map transitions using {@link Map#flyTo}. + * See those functions and {@link AnimationOptions} for information about options available. + * @defaultValue false + */ + linear?: boolean; + /** + * The center of the given bounds relative to the map's center, measured in pixels. + * @defaultValue [0, 0] + */ + offset?: PointLike; + /** + * The maximum zoom level to allow when the map view transitions to the specified bounds. + */ + maxZoom?: number; +}; + +/** + * Options common to map movement methods that involve animation, such as {@link Map#panBy} and + * {@link Map#easeTo}, controlling the duration and easing function of the animation. All properties + * are optional. + * + */ +export type AnimationOptions = { + /** + * The animation's duration, measured in milliseconds. + */ + duration?: number; + /** + * A function taking a time in the range 0..1 and returning a number where 0 is + * the initial state and 1 is the final state. + */ + easing?: (_: number) => number; + /** + * of the target center relative to real map container center at the end of animation. + */ + offset?: PointLike; + /** + * If `false`, no animation will occur. + */ + animate?: boolean; + /** + * If `true`, then the animation is considered essential and will not be affected by + * [`prefers-reduced-motion`](https://developer.mozilla.org/en-US/docs/Web/CSS/\@media/prefers-reduced-motion). + */ + essential?: boolean; +}; + +/** + * A callback hook that allows manipulating the camera and being notified about camera updates before they happen + */ +export type CameraUpdateTransformFunction = (next: { + center: LngLat; + zoom: number; + pitch: number; + bearing: number; + elevation: number; +}) => { + center?: LngLat; + zoom?: number; + pitch?: number; + bearing?: number; + elevation?: number; +}; + +export abstract class Camera extends Evented { + transform: Transform; + handlers: HandlerManager; + + _moving: boolean; + _zooming: boolean; + _rotating: boolean; + _pitching: boolean; + _padding: boolean; + + _bearingSnap: number; + _easeStart: number; + _easeOptions: { + duration?: number; + easing?: (_: number) => number; + }; + _easeId: string | void; + + _onEaseFrame: (_: number) => void; + _onEaseEnd: (easeId?: string) => void; + _easeFrameId: TaskID; + + /** + * @internal + * Used to track accumulated changes during continuous interaction + */ + _requestedCameraState?: Transform; + /** + * A callback used to defer camera updates or apply arbitrary constraints. + * If specified, this Camera instance can be used as a stateless component in React etc. + */ + transformCameraUpdate: CameraUpdateTransformFunction | null; + + abstract _requestRenderFrame(a: () => void): TaskID; + abstract _cancelRenderFrame(_: TaskID): void; + + constructor( + transform: Transform, + options: { + bearingSnap: number; + }, + ) { + super(); + this._moving = false; + this._zooming = false; + this.transform = transform; + this._bearingSnap = options.bearingSnap; + + this.on('moveend', () => { + delete this._requestedCameraState; + }); + } + + /** + * Returns the map's geographical centerpoint. + * + * @returns The map's geographical centerpoint. + * @example + * Return a LngLat object such as `{lng: 0, lat: 0}` + * ```ts + * let center = map.getCenter(); + * // access longitude and latitude values directly + * let {lng, lat} = map.getCenter(); + * ``` + */ + getCenter(): LngLat { + return new LngLat(this.transform.center.lng, this.transform.center.lat); + } + + /** + * Sets the map's geographical centerpoint. Equivalent to `jumpTo({center: center})`. + * + * Triggers the following events: `movestart` and `moveend`. + * + * @param center - The centerpoint to set. + * @param eventData - Additional properties to be added to event objects of events triggered by this method. + * @example + * ```ts + * map.setCenter([-74, 38]); + * ``` + */ + setCenter(center: LngLatLike, eventData?: any) { + return this.jumpTo({ center }, eventData); + } + + /** + * Pans the map by the specified offset. + * + * Triggers the following events: `movestart` and `moveend`. + * + * @param offset - `x` and `y` coordinates by which to pan the map. + * @param options - Options object + * @param eventData - Additional properties to be added to event objects of events triggered by this method. + * @see [Navigate the map with game-like controls](https://maplibre.org/maplibre-gl-js/docs/examples/game-controls/) + */ + panBy(offset: PointLike, options?: AnimationOptions, eventData?: any): this { + offset = Point.convert(offset).mult(-1); + return this.panTo(this.transform.center, extend({ offset }, options), eventData); + } + + /** + * Pans the map to the specified location with an animated transition. + * + * Triggers the following events: `movestart` and `moveend`. + * + * @param lnglat - The location to pan the map to. + * @param options - Options describing the destination and animation of the transition. + * @param eventData - Additional properties to be added to event objects of events triggered by this method. + * @example + * ```ts + * map.panTo([-74, 38]); + * // Specify that the panTo animation should last 5000 milliseconds. + * map.panTo([-74, 38], {duration: 5000}); + * ``` + * @see [Update a feature in realtime](https://maplibre.org/maplibre-gl-js/docs/examples/live-update-feature/) + */ + panTo(lnglat: LngLatLike, options?: AnimationOptions, eventData?: any): this { + return this.easeTo( + extend( + { + center: lnglat, + }, + options, + ), + eventData, + ); + } + + /** + * Returns the map's current zoom level. + * + * @returns The map's current zoom level. + * @example + * ```ts + * map.getZoom(); + * ``` + */ + getZoom(): number { + return this.transform.zoom; + } + + /** + * Sets the map's zoom level. Equivalent to `jumpTo({zoom: zoom})`. + * + * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, and `zoomend`. + * + * @param zoom - The zoom level to set (0-20). + * @param eventData - Additional properties to be added to event objects of events triggered by this method. + * @example + * Zoom to the zoom level 5 without an animated transition + * ```ts + * map.setZoom(5); + * ``` + */ + setZoom(zoom: number, eventData?: any): this { + this.jumpTo({ zoom }, eventData); + return this; + } + + /** + * Zooms the map to the specified zoom level, with an animated transition. + * + * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, and `zoomend`. + * + * @param zoom - The zoom level to transition to. + * @param options - Options object + * @param eventData - Additional properties to be added to event objects of events triggered by this method. + * @example + * ```ts + * // Zoom to the zoom level 5 without an animated transition + * map.zoomTo(5); + * // Zoom to the zoom level 8 with an animated transition + * map.zoomTo(8, { + * duration: 2000, + * offset: [100, 50] + * }); + * ``` + */ + zoomTo(zoom: number, options?: AnimationOptions | null, eventData?: any): this { + return this.easeTo( + extend( + { + zoom, + }, + options, + ), + eventData, + ); + } + + /** + * Increases the map's zoom level by 1. + * + * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, and `zoomend`. + * + * @param options - Options object + * @param eventData - Additional properties to be added to event objects of events triggered by this method. + * @example + * Zoom the map in one level with a custom animation duration + * ```ts + * map.zoomIn({duration: 1000}); + * ``` + */ + zoomIn(options?: AnimationOptions, eventData?: any): this { + this.zoomTo(this.getZoom() + 1, options, eventData); + return this; + } + + /** + * Decreases the map's zoom level by 1. + * + * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, and `zoomend`. + * + * @param options - Options object + * @param eventData - Additional properties to be added to event objects of events triggered by this method. + * @example + * Zoom the map out one level with a custom animation offset + * ```ts + * map.zoomOut({offset: [80, 60]}); + * ``` + */ + zoomOut(options?: AnimationOptions, eventData?: any): this { + this.zoomTo(this.getZoom() - 1, options, eventData); + return this; + } + + /** + * Returns the map's current bearing. The bearing is the compass direction that is "up"; for example, a bearing + * of 90° orients the map so that east is up. + * + * @returns The map's current bearing. + * @see [Navigate the map with game-like controls](https://maplibre.org/maplibre-gl-js/docs/examples/game-controls/) + */ + getBearing(): number { + return this.transform.bearing; + } + + /** + * Sets the map's bearing (rotation). The bearing is the compass direction that is "up"; for example, a bearing + * of 90° orients the map so that east is up. + * + * Equivalent to `jumpTo({bearing: bearing})`. + * + * Triggers the following events: `movestart`, `moveend`, and `rotate`. + * + * @param bearing - The desired bearing. + * @param eventData - Additional properties to be added to event objects of events triggered by this method. + * @example + * Rotate the map to 90 degrees + * ```ts + * map.setBearing(90); + * ``` + */ + setBearing(bearing: number, eventData?: any): this { + this.jumpTo({ bearing }, eventData); + return this; + } + + /** + * Returns the current padding applied around the map viewport. + * + * @returns The current padding around the map viewport. + */ + getPadding(): PaddingOptions { + return this.transform.padding; + } + + /** + * Sets the padding in pixels around the viewport. + * + * Equivalent to `jumpTo({padding: padding})`. + * + * Triggers the following events: `movestart` and `moveend`. + * + * @param padding - The desired padding. + * @param eventData - Additional properties to be added to event objects of events triggered by this method. + * @example + * Sets a left padding of 300px, and a top padding of 50px + * ```ts + * map.setPadding({ left: 300, top: 50 }); + * ``` + */ + setPadding(padding: PaddingOptions, eventData?: any): this { + this.jumpTo({ padding }, eventData); + return this; + } + + /** + * Rotates the map to the specified bearing, with an animated transition. The bearing is the compass direction + * that is "up"; for example, a bearing of 90° orients the map so that east is up. + * + * Triggers the following events: `movestart`, `moveend`, and `rotate`. + * + * @param bearing - The desired bearing. + * @param options - Options object + * @param eventData - Additional properties to be added to event objects of events triggered by this method. + */ + rotateTo(bearing: number, options?: AnimationOptions, eventData?: any): this { + return this.easeTo( + extend( + { + bearing, + }, + options, + ), + eventData, + ); + } + + /** + * Rotates the map so that north is up (0° bearing), with an animated transition. + * + * Triggers the following events: `movestart`, `moveend`, and `rotate`. + * + * @param options - Options object + * @param eventData - Additional properties to be added to event objects of events triggered by this method. + */ + resetNorth(options?: AnimationOptions, eventData?: any): this { + this.rotateTo(0, extend({ duration: 1000 }, options), eventData); + return this; + } + + /** + * Rotates and pitches the map so that north is up (0° bearing) and pitch is 0°, with an animated transition. + * + * Triggers the following events: `movestart`, `move`, `moveend`, `pitchstart`, `pitch`, `pitchend`, and `rotate`. + * + * @param options - Options object + * @param eventData - Additional properties to be added to event objects of events triggered by this method. + */ + resetNorthPitch(options?: AnimationOptions, eventData?: any): this { + this.easeTo( + extend( + { + bearing: 0, + pitch: 0, + duration: 1000, + }, + options, + ), + eventData, + ); + return this; + } + + /** + * Snaps the map so that north is up (0° bearing), if the current bearing is close enough to it (i.e. within the + * `bearingSnap` threshold). + * + * Triggers the following events: `movestart`, `moveend`, and `rotate`. + * + * @param options - Options object + * @param eventData - Additional properties to be added to event objects of events triggered by this method. + */ + snapToNorth(options?: AnimationOptions, eventData?: any): this { + if (Math.abs(this.getBearing()) < this._bearingSnap) { + return this.resetNorth(options, eventData); + } + return this; + } + + /** + * Returns the map's current pitch (tilt). + * + * @returns The map's current pitch, measured in degrees away from the plane of the screen. + */ + getPitch(): number { + return this.transform.pitch; + } + + /** + * Sets the map's pitch (tilt). Equivalent to `jumpTo({pitch: pitch})`. + * + * Triggers the following events: `movestart`, `moveend`, `pitchstart`, and `pitchend`. + * + * @param pitch - The pitch to set, measured in degrees away from the plane of the screen (0-60). + * @param eventData - Additional properties to be added to event objects of events triggered by this method. + */ + setPitch(pitch: number, eventData?: any): this { + this.jumpTo({ pitch }, eventData); + return this; + } + + /** + * @param bounds - Calculate the center for these bounds in the viewport and use + * the highest zoom level up to and including `Map#getMaxZoom()` that fits + * in the viewport. LngLatBounds represent a box that is always axis-aligned with bearing 0. + * @param options - Options object + * @returns If map is able to fit to provided bounds, returns `center`, `zoom`, and `bearing`. + * If map is unable to fit, method will warn and return undefined. + * @example + * ```ts + * let bbox = [[-79, 43], [-73, 45]]; + * let newCameraTransform = map.cameraForBounds(bbox, { + * padding: {top: 10, bottom:25, left: 15, right: 5} + * }); + * ``` + */ + cameraForBounds( + bounds: LngLatBoundsLike, + options?: CameraForBoundsOptions, + ): CenterZoomBearing | undefined { + bounds = LngLatBounds.convert(bounds); + const bearing = (options && options.bearing) || 0; + return this._cameraForBoxAndBearing( + bounds.getNorthWest(), + bounds.getSouthEast(), + bearing, + options, + ); + } + + /** + * @internal + * Calculate the center of these two points in the viewport and use + * the highest zoom level up to and including `Map#getMaxZoom()` that fits + * the points in the viewport at the specified bearing. + * @param p0 - First point + * @param p1 - Second point + * @param bearing - Desired map bearing at end of animation, in degrees + * @param options - the camera options + * @returns If map is able to fit to provided bounds, returns `center`, `zoom`, and `bearing`. + * If map is unable to fit, method will warn and return undefined. + * @example + * ```ts + * let p0 = [-79, 43]; + * let p1 = [-73, 45]; + * let bearing = 90; + * let newCameraTransform = map._cameraForBoxAndBearing(p0, p1, bearing, { + * padding: {top: 10, bottom:25, left: 15, right: 5} + * }); + * ``` + */ + _cameraForBoxAndBearing( + p0: LngLatLike, + p1: LngLatLike, + bearing: number, + options?: CameraForBoundsOptions, + ): CenterZoomBearing | undefined { + const defaultPadding = { + top: 0, + bottom: 0, + right: 0, + left: 0, + }; + options = extend( + { + padding: defaultPadding, + offset: [0, 0], + maxZoom: this.transform.maxZoom, + }, + options, + ); + + if (typeof options.padding === 'number') { + const p = options.padding; + options.padding = { + top: p, + bottom: p, + right: p, + left: p, + }; + } + + options.padding = extend(defaultPadding, options.padding) as PaddingOptions; + const tr = this.transform; + const edgePadding = tr.padding; + + // Consider all corners of the rotated bounding box derived from the given points + // when find the camera position that fits the given points. + const bounds = new LngLatBounds(p0, p1); + const nwWorld = tr.project(bounds.getNorthWest()); + const neWorld = tr.project(bounds.getNorthEast()); + const seWorld = tr.project(bounds.getSouthEast()); + const swWorld = tr.project(bounds.getSouthWest()); + + const bearingRadians = degreesToRadians(-bearing); + + const nwRotatedWorld = nwWorld.rotate(bearingRadians); + const neRotatedWorld = neWorld.rotate(bearingRadians); + const seRotatedWorld = seWorld.rotate(bearingRadians); + const swRotatedWorld = swWorld.rotate(bearingRadians); + + const upperRight = new Point( + Math.max(nwRotatedWorld.x, neRotatedWorld.x, swRotatedWorld.x, seRotatedWorld.x), + Math.max(nwRotatedWorld.y, neRotatedWorld.y, swRotatedWorld.y, seRotatedWorld.y), + ); + + const lowerLeft = new Point( + Math.min(nwRotatedWorld.x, neRotatedWorld.x, swRotatedWorld.x, seRotatedWorld.x), + Math.min(nwRotatedWorld.y, neRotatedWorld.y, swRotatedWorld.y, seRotatedWorld.y), + ); + + // Calculate zoom: consider the original bbox and padding. + const size = upperRight.sub(lowerLeft); + const scaleX = + (tr.width - + (edgePadding.left + edgePadding.right + options.padding.left + options.padding.right)) / + size.x; + const scaleY = + (tr.height - + (edgePadding.top + edgePadding.bottom + options.padding.top + options.padding.bottom)) / + size.y; + + if (scaleY < 0 || scaleX < 0) { + warnOnce('Map cannot fit within canvas with the given bounds, padding, and/or offset.'); + return undefined; + } + + const zoom = Math.min(tr.scaleZoom(tr.scale * Math.min(scaleX, scaleY)), options.maxZoom); + + // Calculate center: apply the zoom, the configured offset, as well as offset that exists as a result of padding. + const offset = Point.convert(options.offset); + const paddingOffsetX = (options.padding.left - options.padding.right) / 2; + const paddingOffsetY = (options.padding.top - options.padding.bottom) / 2; + const paddingOffset = new Point(paddingOffsetX, paddingOffsetY); + const rotatedPaddingOffset = paddingOffset.rotate(degreesToRadians(bearing)); + const offsetAtInitialZoom = offset.add(rotatedPaddingOffset); + const offsetAtFinalZoom = offsetAtInitialZoom.mult(tr.scale / tr.zoomScale(zoom)); + + const center = tr.unproject( + // either world diagonal can be used (NW-SE or NE-SW) + nwWorld.add(seWorld).div(2).sub(offsetAtFinalZoom), + ); + + return { + center, + zoom, + bearing, + }; + } + + /** + * Pans and zooms the map to contain its visible area within the specified geographical bounds. + * This function will also reset the map's bearing to 0 if bearing is nonzero. + * + * Triggers the following events: `movestart` and `moveend`. + * + * @param bounds - Center these bounds in the viewport and use the highest + * zoom level up to and including `Map#getMaxZoom()` that fits them in the viewport. + * @param options - Options supports all properties from {@link AnimationOptions} and {@link CameraOptions} in addition to the fields below. + * @param eventData - Additional properties to be added to event objects of events triggered by this method. + * @example + * ```ts + * let bbox = [[-79, 43], [-73, 45]]; + * map.fitBounds(bbox, { + * padding: {top: 10, bottom:25, left: 15, right: 5} + * }); + * ``` + * @see [Fit a map to a bounding box](https://maplibre.org/maplibre-gl-js/docs/examples/fitbounds/) + */ + fitBounds(bounds: LngLatBoundsLike, options?: FitBoundsOptions, eventData?: any): this { + return this._fitInternal(this.cameraForBounds(bounds, options), options, eventData); + } + + /** + * Pans, rotates and zooms the map to to fit the box made by points p0 and p1 + * once the map is rotated to the specified bearing. To zoom without rotating, + * pass in the current map bearing. + * + * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, `zoomend` and `rotate`. + * + * @param p0 - First point on screen, in pixel coordinates + * @param p1 - Second point on screen, in pixel coordinates + * @param bearing - Desired map bearing at end of animation, in degrees + * @param options - Options object + * @param eventData - Additional properties to be added to event objects of events triggered by this method. + * @example + * ```ts + * let p0 = [220, 400]; + * let p1 = [500, 900]; + * map.fitScreenCoordinates(p0, p1, map.getBearing(), { + * padding: {top: 10, bottom:25, left: 15, right: 5} + * }); + * ``` + * @see Used by {@link BoxZoomHandler} + */ + fitScreenCoordinates( + p0: PointLike, + p1: PointLike, + bearing: number, + options?: FitBoundsOptions, + eventData?: any, + ): this { + return this._fitInternal( + this._cameraForBoxAndBearing( + this.transform.pointLocation(Point.convert(p0)), + this.transform.pointLocation(Point.convert(p1)), + bearing, + options, + ), + options, + eventData, + ); + } + + _fitInternal( + calculatedOptions?: CenterZoomBearing, + options?: FitBoundsOptions, + eventData?: any, + ): this { + // cameraForBounds warns + returns undefined if unable to fit: + if (!calculatedOptions) return this; + + options = extend(calculatedOptions, options); + // Explicitly remove the padding field because, calculatedOptions already accounts for padding by setting zoom and center accordingly. + delete options.padding; + + return options.linear ? this.easeTo(options, eventData) : this.flyTo(options, eventData); + } + + /** + * Changes any combination of center, zoom, bearing, and pitch, without + * an animated transition. The map will retain its current values for any + * details not specified in `options`. + * + * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, `zoomend`, `pitchstart`, + * `pitch`, `pitchend`, and `rotate`. + * + * @param options - Options object + * @param eventData - Additional properties to be added to event objects of events triggered by this method. + * @example + * ```ts + * // jump to coordinates at current zoom + * map.jumpTo({center: [0, 0]}); + * // jump with zoom, pitch, and bearing options + * map.jumpTo({ + * center: [0, 0], + * zoom: 8, + * pitch: 45, + * bearing: 90 + * }); + * ``` + * @see [Jump to a series of locations](https://maplibre.org/maplibre-gl-js/docs/examples/jump-to/) + * @see [Update a feature in realtime](https://maplibre.org/maplibre-gl-js/docs/examples/live-update-feature/) + */ + jumpTo(options: JumpToOptions, eventData?: any): this { + this.stop(); + + const tr = this._getTransformForUpdate(); + let zoomChanged = false, + bearingChanged = false, + pitchChanged = false; + + if ('zoom' in options && tr.zoom !== +options.zoom) { + zoomChanged = true; + tr.zoom = +options.zoom; + } + + if (options.center !== undefined) { + tr.center = LngLat.convert(options.center); + } + + if ('bearing' in options && tr.bearing !== +options.bearing) { + bearingChanged = true; + tr.bearing = +options.bearing; + } + + if ('pitch' in options && tr.pitch !== +options.pitch) { + pitchChanged = true; + tr.pitch = +options.pitch; + } + + if (options.padding != null && !tr.isPaddingEqual(options.padding)) { + tr.padding = options.padding; + } + this._applyUpdatedTransform(tr); + + this.fire(new Event('movestart', eventData)).fire(new Event('move', eventData)); + + if (zoomChanged) { + this.fire(new Event('zoomstart', eventData)) + .fire(new Event('zoom', eventData)) + .fire(new Event('zoomend', eventData)); + } + + if (bearingChanged) { + this.fire(new Event('rotatestart', eventData)) + .fire(new Event('rotate', eventData)) + .fire(new Event('rotateend', eventData)); + } + + if (pitchChanged) { + this.fire(new Event('pitchstart', eventData)) + .fire(new Event('pitch', eventData)) + .fire(new Event('pitchend', eventData)); + } + + return this.fire(new Event('moveend', eventData)); + } + + /** + * Calculates pitch, zoom and bearing for looking at `newCenter` with the camera position being `newCenter` + * and returns them as {@link CameraOptions}. + * @param from - The camera to look from + * @param altitudeFrom - The altitude of the camera to look from + * @param to - The center to look at + * @param altitudeTo - Optional altitude of the center to look at. If none given the ground height will be used. + * @returns the calculated camera options + */ + calculateCameraOptionsFromTo( + from: LngLat, + altitudeFrom: number, + to: LngLat, + altitudeTo: number = 0, + ): CameraOptions { + const fromMerc = MercatorCoordinate.fromLngLat(from, altitudeFrom); + const toMerc = MercatorCoordinate.fromLngLat(to, altitudeTo); + const dx = toMerc.x - fromMerc.x; + const dy = toMerc.y - fromMerc.y; + const dz = toMerc.z - fromMerc.z; + + const distance3D = Math.hypot(dx, dy, dz); + if (distance3D === 0) throw new Error("Can't calculate camera options with same From and To"); + + const groundDistance = Math.hypot(dx, dy); + + const zoom = this.transform.scaleZoom( + this.transform.cameraToCenterDistance / distance3D / this.transform.tileSize, + ); + const bearing = (Math.atan2(dx, -dy) * 180) / Math.PI; + let pitch = (Math.acos(groundDistance / distance3D) * 180) / Math.PI; + pitch = dz < 0 ? 90 - pitch : 90 + pitch; + + return { + center: toMerc.toLngLat(), + zoom, + pitch, + bearing, + }; + } + + /** + * Changes any combination of `center`, `zoom`, `bearing`, `pitch`, and `padding` with an animated transition + * between old and new values. The map will retain its current values for any + * details not specified in `options`. + * + * Note: The transition will happen instantly if the user has enabled + * the `reduced motion` accessibility feature enabled in their operating system, + * unless `options` includes `essential: true`. + * + * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, `zoomend`, `pitchstart`, + * `pitch`, `pitchend`, and `rotate`. + * + * @param options - Options describing the destination and animation of the transition. + * Accepts {@link CameraOptions} and {@link AnimationOptions}. + * @param eventData - Additional properties to be added to event objects of events triggered by this method. + * @see [Navigate the map with game-like controls](https://maplibre.org/maplibre-gl-js/docs/examples/game-controls/) + */ + easeTo( + options: EaseToOptions & { + easeId?: string; + noMoveStart?: boolean; + }, + eventData?: any, + ): this { + this._stop(false, options.easeId); + + options = extend( + { + offset: [0, 0], + duration: 500, + easing: defaultEasing, + }, + options, + ); + + if (options.animate === false || (!options.essential && browser.prefersReducedMotion)) + options.duration = 0; + + const tr = this._getTransformForUpdate(), + startZoom = this.getZoom(), + startBearing = this.getBearing(), + startPitch = this.getPitch(), + startPadding = this.getPadding(), + bearing = + 'bearing' in options ? this._normalizeBearing(options.bearing, startBearing) : startBearing, + pitch = 'pitch' in options ? +options.pitch : startPitch, + padding = 'padding' in options ? options.padding : tr.padding; + + const offsetAsPoint = Point.convert(options.offset); + let pointAtOffset = tr.centerPoint.add(offsetAsPoint); + const locationAtOffset = tr.pointLocation(pointAtOffset); + + const { center, zoom } = tr.getConstrained( + LngLat.convert(options.center || locationAtOffset), + options.zoom ?? startZoom, + ); + this._normalizeCenter(center); + + const from = tr.project(locationAtOffset); + const delta = tr.project(center).sub(from); + const finalScale = tr.zoomScale(zoom - startZoom); + + let around, aroundPoint; + + if (options.around) { + around = LngLat.convert(options.around); + aroundPoint = tr.locationPoint(around); + } + + const currently = { + moving: this._moving, + zooming: this._zooming, + rotating: this._rotating, + pitching: this._pitching, + }; + + this._zooming = this._zooming || zoom !== startZoom; + this._rotating = this._rotating || startBearing !== bearing; + this._pitching = this._pitching || pitch !== startPitch; + this._padding = !tr.isPaddingEqual(padding as PaddingOptions); + + this._easeId = options.easeId; + this._prepareEase(eventData, options.noMoveStart, currently); + + this._ease( + (k) => { + if (this._zooming) { + tr.zoom = interpolates.number(startZoom, zoom, k); + } + if (this._rotating) { + tr.bearing = interpolates.number(startBearing, bearing, k); + } + if (this._pitching) { + tr.pitch = interpolates.number(startPitch, pitch, k); + } + if (this._padding) { + tr.interpolatePadding(startPadding, padding as PaddingOptions, k); + // When padding is being applied, Transform#centerPoint is changing continuously, + // thus we need to recalculate offsetPoint every frame + pointAtOffset = tr.centerPoint.add(offsetAsPoint); + } + + if (around) { + tr.setLocationAtPoint(around, aroundPoint); + } else { + const scale = tr.zoomScale(tr.zoom - startZoom); + const base = zoom > startZoom ? Math.min(2, finalScale) : Math.max(0.5, finalScale); + const speedup = Math.pow(base, 1 - k); + const newCenter = tr.unproject(from.add(delta.mult(k * speedup)).mult(scale)); + tr.setLocationAtPoint(tr.renderWorldCopies ? newCenter.wrap() : newCenter, pointAtOffset); + } + + this._applyUpdatedTransform(tr); + + this._fireMoveEvents(eventData); + }, + (interruptingEaseId?: string) => { + this._afterEase(eventData, interruptingEaseId); + }, + options as any, + ); + + return this; + } + + _prepareEase(eventData: any, noMoveStart: boolean, currently: any = {}) { + this._moving = true; + if (!noMoveStart && !currently.moving) { + this.fire(new Event('movestart', eventData)); + } + if (this._zooming && !currently.zooming) { + this.fire(new Event('zoomstart', eventData)); + } + if (this._rotating && !currently.rotating) { + this.fire(new Event('rotatestart', eventData)); + } + if (this._pitching && !currently.pitching) { + this.fire(new Event('pitchstart', eventData)); + } + } + + /** + * @internal + * Called when the camera is about to be manipulated. + * If `transformCameraUpdate` is specified, a copy of the current transform is created to track the accumulated changes. + * This underlying transform represents the "desired state" proposed by input handlers / animations / UI controls. + * It may differ from the state used for rendering (`this.transform`). + * @returns Transform to apply changes to + */ + _getTransformForUpdate(): Transform { + if (!this.transformCameraUpdate) return this.transform; + + if (!this._requestedCameraState) { + this._requestedCameraState = this.transform.clone(); + } + return this._requestedCameraState; + } + + /** + * @internal + * Called after the camera is done being manipulated. + * @param tr - the requested camera end state + * Call `transformCameraUpdate` if present, and then apply the "approved" changes. + */ + _applyUpdatedTransform(tr: Transform) { + if (!this.transformCameraUpdate) return; + + const nextTransform = tr.clone(); + const { center, zoom, pitch, bearing, elevation } = this.transformCameraUpdate(nextTransform); + if (center) nextTransform.center = center; + if (zoom !== undefined) nextTransform.zoom = zoom; + if (pitch !== undefined) nextTransform.pitch = pitch; + if (bearing !== undefined) nextTransform.bearing = bearing; + if (elevation !== undefined) nextTransform.elevation = elevation; + this.transform.apply(nextTransform); + } + + _fireMoveEvents(eventData?: any) { + this.fire(new Event('move', eventData)); + if (this._zooming) { + this.fire(new Event('zoom', eventData)); + } + if (this._rotating) { + this.fire(new Event('rotate', eventData)); + } + if (this._pitching) { + this.fire(new Event('pitch', eventData)); + } + } + + _afterEase(eventData?: any, easeId?: string) { + // if this easing is being stopped to start another easing with + // the same id then don't fire any events to avoid extra start/stop events + if (this._easeId && easeId && this._easeId === easeId) { + return; + } + delete this._easeId; + + const wasZooming = this._zooming; + const wasRotating = this._rotating; + const wasPitching = this._pitching; + this._moving = false; + this._zooming = false; + this._rotating = false; + this._pitching = false; + this._padding = false; + + if (wasZooming) { + this.fire(new Event('zoomend', eventData)); + } + if (wasRotating) { + this.fire(new Event('rotateend', eventData)); + } + if (wasPitching) { + this.fire(new Event('pitchend', eventData)); + } + this.fire(new Event('moveend', eventData)); + } + + /** + * Changes any combination of center, zoom, bearing, and pitch, animating the transition along a curve that + * evokes flight. The animation seamlessly incorporates zooming and panning to help + * the user maintain her bearings even after traversing a great distance. + * + * Note: The animation will be skipped, and this will behave equivalently to `jumpTo` + * if the user has the `reduced motion` accessibility feature enabled in their operating system, + * unless 'options' includes `essential: true`. + * + * Triggers the following events: `movestart`, `move`, `moveend`, `zoomstart`, `zoom`, `zoomend`, `pitchstart`, + * `pitch`, `pitchend`, and `rotate`. + * + * @param options - Options describing the destination and animation of the transition. + * Accepts {@link CameraOptions}, {@link AnimationOptions}, + * and the following additional options. + * @param eventData - Additional properties to be added to event objects of events triggered by this method. + * @example + * ```ts + * // fly with default options to null island + * map.flyTo({center: [0, 0], zoom: 9}); + * // using flyTo options + * map.flyTo({ + * center: [0, 0], + * zoom: 9, + * speed: 0.2, + * curve: 1, + * easing(t) { + * return t; + * } + * }); + * ``` + * @see [Fly to a location](https://maplibre.org/maplibre-gl-js/docs/examples/flyto/) + * @see [Slowly fly to a location](https://maplibre.org/maplibre-gl-js/docs/examples/flyto-options/) + * @see [Fly to a location based on scroll position](https://maplibre.org/maplibre-gl-js/docs/examples/scroll-fly-to/) + */ + flyTo(options: FlyToOptions, eventData?: any): this { + // Fall through to jumpTo if user has set prefers-reduced-motion + if (!options.essential && browser.prefersReducedMotion) { + const coercedOptions = pick(options, [ + 'center', + 'zoom', + 'bearing', + 'pitch', + 'around', + ]) as CameraOptions; + return this.jumpTo(coercedOptions, eventData); + } + + // This method implements an “optimal path” animation, as detailed in: + // + // Van Wijk, Jarke J.; Nuij, Wim A. A. “Smooth and efficient zooming and panning.” INFOVIS + // ’03. pp. 15–22. . + // + // Where applicable, local variable documentation begins with the associated variable or + // function in van Wijk (2003). + + this.stop(); + + options = extend( + { + offset: [0, 0], + speed: 1.2, + curve: 1.42, + easing: defaultEasing, + }, + options, + ); + + const tr = this._getTransformForUpdate(), + startZoom = this.getZoom(), + startBearing = this.getBearing(), + startPitch = this.getPitch(), + startPadding = this.getPadding(); + + const bearing = + 'bearing' in options ? this._normalizeBearing(options.bearing, startBearing) : startBearing; + const pitch = 'pitch' in options ? +options.pitch : startPitch; + const padding = 'padding' in options ? options.padding : tr.padding; + + const offsetAsPoint = Point.convert(options.offset); + let pointAtOffset = tr.centerPoint.add(offsetAsPoint); + const locationAtOffset = tr.pointLocation(pointAtOffset); + + const { center, zoom } = tr.getConstrained( + LngLat.convert(options.center || locationAtOffset), + options.zoom ?? startZoom, + ); + this._normalizeCenter(center); + const scale = tr.zoomScale(zoom - startZoom); + + const from = tr.project(locationAtOffset); + const delta = tr.project(center).sub(from); + + let rho = options.curve; + + // w₀: Initial visible span, measured in pixels at the initial scale. + const w0 = Math.max(tr.width, tr.height), + // w₁: Final visible span, measured in pixels with respect to the initial scale. + w1 = w0 / scale, + // Length of the flight path as projected onto the ground plane, measured in pixels from + // the world image origin at the initial scale. + u1 = delta.mag(); + + if ('minZoom' in options) { + const minZoom = clamp(Math.min(options.minZoom, startZoom, zoom), tr.minZoom, tr.maxZoom); + // wm: Maximum visible span, measured in pixels with respect to the initial + // scale. + const wMax = w0 / tr.zoomScale(minZoom - startZoom); + rho = Math.sqrt((wMax / u1) * 2); + } + + // ρ² + const rho2 = rho * rho; + + /** + * rᵢ: Returns the zoom-out factor at one end of the animation. + * + * @param descent - `true` for the descent, `false` for the ascent + */ + function zoomOutFactor(descent: boolean) { + const b = + (w1 * w1 - w0 * w0 + (descent ? -1 : 1) * rho2 * rho2 * u1 * u1) / + (2 * (descent ? w1 : w0) * rho2 * u1); + return Math.log(Math.sqrt(b * b + 1) - b); + } + + function sinh(n) { + return (Math.exp(n) - Math.exp(-n)) / 2; + } + function cosh(n) { + return (Math.exp(n) + Math.exp(-n)) / 2; + } + function tanh(n) { + return sinh(n) / cosh(n); + } + + // r₀: Zoom-out factor during ascent. + const r0 = zoomOutFactor(false); + + // w(s): Returns the visible span on the ground, measured in pixels with respect to the + // initial scale. Assumes an angular field of view of 2 arctan ½ ≈ 53°. + let w: (_: number) => number = function (s) { + return cosh(r0) / cosh(r0 + rho * s); + }; + + // u(s): Returns the distance along the flight path as projected onto the ground plane, + // measured in pixels from the world image origin at the initial scale. + let u: (_: number) => number = function (s) { + return (w0 * ((cosh(r0) * tanh(r0 + rho * s) - sinh(r0)) / rho2)) / u1; + }; + + // S: Total length of the flight path, measured in ρ-screenfuls. + let S = (zoomOutFactor(true) - r0) / rho; + + // When u₀ = u₁, the optimal path doesn’t require both ascent and descent. + if (Math.abs(u1) < 0.000001 || !isFinite(S)) { + // Perform a more or less instantaneous transition if the path is too short. + if (Math.abs(w0 - w1) < 0.000001) return this.easeTo(options, eventData); + + const k = w1 < w0 ? -1 : 1; + S = Math.abs(Math.log(w1 / w0)) / rho; + + u = () => 0; + w = (s) => Math.exp(k * rho * s); + } + + if ('duration' in options) { + options.duration = +options.duration; + } else { + const V = 'screenSpeed' in options ? +options.screenSpeed / rho : +options.speed; + options.duration = (1000 * S) / V; + } + + if (options.maxDuration && options.duration > options.maxDuration) { + options.duration = 0; + } + + this._zooming = true; + this._rotating = startBearing !== bearing; + this._pitching = pitch !== startPitch; + this._padding = !tr.isPaddingEqual(padding as PaddingOptions); + + this._prepareEase(eventData, false); + + this._ease( + (k) => { + // s: The distance traveled along the flight path, measured in ρ-screenfuls. + const s = k * S; + const scale = 1 / w(s); + tr.zoom = k === 1 ? zoom : startZoom + tr.scaleZoom(scale); + + if (this._rotating) { + tr.bearing = interpolates.number(startBearing, bearing, k); + } + if (this._pitching) { + tr.pitch = interpolates.number(startPitch, pitch, k); + } + if (this._padding) { + tr.interpolatePadding(startPadding, padding as PaddingOptions, k); + // When padding is being applied, Transform#centerPoint is changing continuously, + // thus we need to recalculate offsetPoint every frame + pointAtOffset = tr.centerPoint.add(offsetAsPoint); + } + + const newCenter = k === 1 ? center : tr.unproject(from.add(delta.mult(u(s))).mult(scale)); + tr.setLocationAtPoint(tr.renderWorldCopies ? newCenter.wrap() : newCenter, pointAtOffset); + + this._applyUpdatedTransform(tr); + + this._fireMoveEvents(eventData); + }, + () => { + this._afterEase(eventData); + }, + options, + ); + + return this; + } + + isEasing() { + return !!this._easeFrameId; + } + + /** + * Stops any animated transition underway. + */ + stop(): this { + return this._stop(); + } + + _stop(allowGestures?: boolean, easeId?: string): this { + if (this._easeFrameId) { + this._cancelRenderFrame(this._easeFrameId); + delete this._easeFrameId; + delete this._onEaseFrame; + } + + if (this._onEaseEnd) { + // The _onEaseEnd function might emit events which trigger new + // animation, which sets a new _onEaseEnd. Ensure we don't delete + // it unintentionally. + const onEaseEnd = this._onEaseEnd; + delete this._onEaseEnd; + onEaseEnd.call(this, easeId); + } + if (!allowGestures) { + this.handlers?.stop(false); + } + return this; + } + + _ease( + frame: (_: number) => void, + finish: () => void, + options: { + animate?: boolean; + duration?: number; + easing?: (_: number) => number; + }, + ) { + if (options.animate === false || options.duration === 0) { + frame(1); + finish(); + } else { + this._easeStart = browser.now(); + this._easeOptions = options; + this._onEaseFrame = frame; + this._onEaseEnd = finish; + this._easeFrameId = this._requestRenderFrame(this._renderFrameCallback); + } + } + + // Callback for map._requestRenderFrame + _renderFrameCallback = () => { + const t = Math.min((browser.now() - this._easeStart) / this._easeOptions.duration, 1); + this._onEaseFrame(this._easeOptions.easing(t)); + + // if _stop is called during _onEaseFrame from _fireMoveEvents we should avoid a new _requestRenderFrame, checking it by ensuring _easeFrameId was not deleted + if (t < 1 && this._easeFrameId) { + this._easeFrameId = this._requestRenderFrame(this._renderFrameCallback); + } else { + this.stop(); + } + }; + + // convert bearing so that it's numerically close to the current one so that it interpolates properly + _normalizeBearing(bearing: number, currentBearing: number) { + bearing = wrap(bearing, -180, 180); + const diff = Math.abs(bearing - currentBearing); + if (Math.abs(bearing - 360 - currentBearing) < diff) bearing -= 360; + if (Math.abs(bearing + 360 - currentBearing) < diff) bearing += 360; + return bearing; + } + + // If a path crossing the antimeridian would be shorter, extend the final coordinate so that + // interpolating between the two endpoints will cross it. + _normalizeCenter(center: LngLat) { + const tr = this.transform; + if (!tr.renderWorldCopies || tr.lngRange) return; + + const delta = center.lng - tr.center.lng; + center.lng += delta > 180 ? -360 : delta < -180 ? 360 : 0; + } +} diff --git a/packages/map/src/map/css/l7.css b/packages/map/src/map/css/l7.css new file mode 100644 index 00000000000..4a6d99c3970 --- /dev/null +++ b/packages/map/src/map/css/l7.css @@ -0,0 +1,163 @@ +.l7-map { + font: + 12px/20px 'Helvetica Neue', + Arial, + Helvetica, + sans-serif; + overflow: hidden; + position: relative; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} + +.l7-canvas { + position: absolute; + left: 0; + top: 0; +} + +.l7-map:-webkit-full-screen { + width: 100%; + height: 100%; +} + +.l7-canary { + background-color: salmon; +} + +.l7-canvas-container.l7-interactive, +.l7-ctrl-group button.l7-ctrl-compass { + cursor: grab; + user-select: none; +} + +.l7-canvas-container.l7-interactive.l7-track-pointer { + cursor: pointer; +} + +.l7-canvas-container.l7-interactive:active, +.l7-ctrl-group button.l7-ctrl-compass:active { + cursor: grabbing; +} + +.l7-canvas-container.l7-touch-zoom-rotate, +.l7-canvas-container.l7-touch-zoom-rotate .l7-canvas { + touch-action: pan-x pan-y; +} + +.l7-canvas-container.l7-touch-drag-pan, +.l7-canvas-container.l7-touch-drag-pan .l7-canvas { + touch-action: pinch-zoom; +} + +.l7-canvas-container.l7-touch-zoom-rotate.l7-touch-drag-pan, +.l7-canvas-container.l7-touch-zoom-rotate.l7-touch-drag-pan .l7-canvas { + touch-action: none; +} + +.l7-canvas-container.l7-touch-drag-pan.l7-cooperative-gestures, +.l7-canvas-container.l7-touch-drag-pan.l7-cooperative-gestures .l7-canvas { + touch-action: pan-x pan-y; +} + +.l7-cooperative-gesture-screen { + background: rgba(0 0 0 / 40%); + position: absolute; + inset: 0; + display: flex; + justify-content: center; + align-items: center; + color: white; + padding: 1rem; + font-size: 1.4em; + line-height: 1.2; + opacity: 0; + pointer-events: none; + transition: opacity 1s ease 1s; + z-index: 99999; +} + +.l7-cooperative-gesture-screen.l7-show { + opacity: 1; + transition: opacity 0.05s; +} + +.l7-cooperative-gesture-screen .l7-mobile-message { + display: none; +} + +@media (hover: none), (width <= 480px) { + .l7-cooperative-gesture-screen .l7-desktop-message { + display: none; + } + + .l7-cooperative-gesture-screen .l7-mobile-message { + display: block; + } +} + +.l7-ctrl-top-left, +.l7-ctrl-top-right, +.l7-ctrl-bottom-left, +.l7-ctrl-bottom-right { + position: absolute; + pointer-events: none; + z-index: 2; +} +.l7-ctrl-top-left { + top: 0; + left: 0; +} +.l7-ctrl-top-right { + top: 0; + right: 0; +} +.l7-ctrl-bottom-left { + bottom: 0; + left: 0; +} +.l7-ctrl-bottom-right { + right: 0; + bottom: 0; +} + +.l7-ctrl { + clear: both; + pointer-events: auto; + + /* workaround for a Safari bug https://github.com/mapbox/mapbox-gl-js/issues/8185 */ + transform: translate(0, 0); +} +.l7-ctrl-top-left .l7-ctrl { + margin: 10px 0 0 10px; + float: left; +} +.l7-ctrl-top-right .l7-ctrl { + margin: 10px 10px 0 0; + float: right; +} +.l7-ctrl-bottom-left .l7-ctrl { + margin: 0 0 10px 10px; + float: left; +} +.l7-ctrl-bottom-right .l7-ctrl { + margin: 0 10px 10px 0; + float: right; +} + +.l7-crosshair, +.l7-crosshair .l7-interactive, +.l7-crosshair .l7-interactive:active { + cursor: crosshair; +} + +.l7-boxzoom { + position: absolute; + top: 0; + left: 0; + width: 0; + height: 0; + background: #fff; + border: 2px dotted #202020; + opacity: 0.5; + z-index: 10; +} diff --git a/packages/map/src/map/events.ts b/packages/map/src/map/events.ts new file mode 100644 index 00000000000..8502ca679cd --- /dev/null +++ b/packages/map/src/map/events.ts @@ -0,0 +1,469 @@ +import { Event } from './util/evented'; + +import Point from '@mapbox/point-geometry'; +import { DOM } from './util/dom'; + +import type { LngLat } from './geo/lng_lat'; +import type { Map } from './map'; + +/** + * `MapEventType` - a mapping between the event name and the event value. + * These events are used with the {@link Map#on} method. + * When using a `layerId` with {@link Map#on} method, please refer to {@link MapLayerEventType}. + * The following example can be used for all the events. + * + * @group Event Related + * @example + * ```ts + * // Initialize the map + * let map = new Map({ // map options }); + * // Set an event listener + * map.on('the-event-name', () => { + * console.log('An event has occurred!'); + * }); + * ``` + */ +export type MapEventType = { + /** + * Fired when an error occurs. This is GL JS's primary error reporting + * mechanism. We use an event instead of `throw` to better accommodate + * asynchronous operations. If no listeners are bound to the `error` event, the + * error will be printed to the console. + */ + error: ErrorEvent; + /** + * Fired after the last frame rendered before the map enters an + * "idle" state: + * + * - No camera transitions are in progress + * - All currently requested tiles have loaded + * - All fade/transition animations have completed + */ + idle: MapLibreEvent; + /** + * Fired immediately after the map has been removed with {@link Map#remove}. + */ + remove: MapLibreEvent; + /** + * Fired immediately after the map has been resized. + */ + resize: MapLibreEvent; + /** + * Fired when the user cancels a "box zoom" interaction, or when the bounding box does not meet the minimum size threshold. + * See {@link BoxZoomHandler}. + */ + boxzoomcancel: MapLibreZoomEvent; + /** + * Fired when a "box zoom" interaction starts. See {@link BoxZoomHandler}. + */ + boxzoomstart: MapLibreZoomEvent; + /** + * Fired when a "box zoom" interaction ends. See {@link BoxZoomHandler}. + */ + boxzoomend: MapLibreZoomEvent; + /** + * Fired when a [`touchcancel`](https://developer.mozilla.org/en-US/docs/Web/Events/touchcancel) event occurs within the map. + */ + touchcancel: MapTouchEvent; + /** + * Fired when a [`touchmove`](https://developer.mozilla.org/en-US/docs/Web/Events/touchmove) event occurs within the map. + * @see [Create a draggable point](https://maplibre.org/maplibre-gl-js/docs/examples/drag-a-point/) + */ + touchmove: MapTouchEvent; + /** + * Fired when a [`touchend`](https://developer.mozilla.org/en-US/docs/Web/Events/touchend) event occurs within the map. + * @see [Create a draggable point](https://maplibre.org/maplibre-gl-js/docs/examples/drag-a-point/) + */ + touchend: MapTouchEvent; + /** + * Fired when a [`touchstart`](https://developer.mozilla.org/en-US/docs/Web/Events/touchstart) event occurs within the map. + * @see [Create a draggable point](https://maplibre.org/maplibre-gl-js/docs/examples/drag-a-point/) + */ + touchstart: MapTouchEvent; + /** + * Fired when a pointing device (usually a mouse) is pressed and released at the same point on the map. + * + * @see [Measure distances](https://maplibre.org/maplibre-gl-js/docs/examples/measure/) + * @see [Center the map on a clicked symbol](https://maplibre.org/maplibre-gl-js/docs/examples/center-on-symbol/) + */ + click: MapMouseEvent; + /** + * Fired when the right button of the mouse is clicked or the context menu key is pressed within the map. + */ + contextmenu: MapMouseEvent; + /** + * Fired when a pointing device (usually a mouse) is pressed and released twice at the same point on the map in rapid succession. + * + * **Note:** Under normal conditions, this event will be preceded by two `click` events. + */ + dblclick: MapMouseEvent; + /** + * Fired when a pointing device (usually a mouse) is moved while the cursor is inside the map. + * As you move the cursor across the map, the event will fire every time the cursor changes position within the map. + * + * @see [Get coordinates of the mouse pointer](https://maplibre.org/maplibre-gl-js/docs/examples/mouse-position/) + * @see [Highlight features under the mouse pointer](https://maplibre.org/maplibre-gl-js/docs/examples/hover-styles/) + * @see [Display a popup on over](https://maplibre.org/maplibre-gl-js/docs/examples/popup-on-hover/) + */ + mousemove: MapMouseEvent; + /** + * Fired when a pointing device (usually a mouse) is released within the map. + * + * @see [Create a draggable point](https://maplibre.org/maplibre-gl-js/docs/examples/drag-a-point/) + */ + mouseup: MapMouseEvent; + /** + * Fired when a pointing device (usually a mouse) is pressed within the map. + * + * @see [Create a draggable point](https://maplibre.org/maplibre-gl-js/docs/examples/drag-a-point/) + */ + mousedown: MapMouseEvent; + /** + * Fired when a point device (usually a mouse) leaves the map's canvas. + */ + mouseout: MapMouseEvent; + /** + * Fired when a pointing device (usually a mouse) is moved within the map. + * As you move the cursor across a web page containing a map, + * the event will fire each time it enters the map or any child elements. + * + * @see [Get coordinates of the mouse pointer](https://maplibre.org/maplibre-gl-js/docs/examples/mouse-position/) + * @see [Highlight features under the mouse pointer](https://maplibre.org/maplibre-gl-js/docs/examples/hover-styles/) + * @see [Display a popup on hover](https://maplibre.org/maplibre-gl-js/docs/examples/popup-on-hover/) + */ + mouseover: MapMouseEvent; + /** + * Fired just before the map begins a transition from one + * view to another, as the result of either user interaction or methods such as {@link Map#jumpTo}. + * + */ + movestart: MapLibreEvent; + /** + * Fired repeatedly during an animated transition from one view to + * another, as the result of either user interaction or methods such as {@link Map#flyTo}. + * + * @see [Display HTML clusters with custom properties](https://maplibre.org/maplibre-gl-js/docs/examples/cluster-html/) + */ + move: MapLibreEvent; + /** + * Fired just after the map completes a transition from one + * view to another, as the result of either user interaction or methods such as {@link Map#jumpTo}. + * + * @see [Display HTML clusters with custom properties](https://maplibre.org/maplibre-gl-js/docs/examples/cluster-html/) + */ + moveend: MapLibreEvent; + /** + * Fired just before the map begins a transition from one zoom level to another, + * as the result of either user interaction or methods such as {@link Map#flyTo}. + */ + zoomstart: MapLibreEvent; + /** + * Fired repeatedly during an animated transition from one zoom level to another, + * as the result of either user interaction or methods such as {@link Map#flyTo}. + */ + zoom: MapLibreEvent; + /** + * Fired just after the map completes a transition from one zoom level to another, + * as the result of either user interaction or methods such as {@link Map#flyTo}. + */ + zoomend: MapLibreEvent; + /** + * Fired when a "drag to rotate" interaction starts. See {@link DragRotateHandler}. + */ + rotatestart: MapLibreEvent; + /** + * Fired repeatedly during a "drag to rotate" interaction. See {@link DragRotateHandler}. + */ + rotate: MapLibreEvent; + /** + * Fired when a "drag to rotate" interaction ends. See {@link DragRotateHandler}. + */ + rotateend: MapLibreEvent; + /** + * Fired when a "drag to pan" interaction starts. See {@link DragPanHandler}. + */ + dragstart: MapLibreEvent; + /** + * Fired repeatedly during a "drag to pan" interaction. See {@link DragPanHandler}. + */ + drag: MapLibreEvent; + /** + * Fired when a "drag to pan" interaction ends. See {@link DragPanHandler}. + * @see [Create a draggable marker](https://maplibre.org/maplibre-gl-js/docs/examples/drag-a-marker/) + */ + dragend: MapLibreEvent; + /** + * Fired whenever the map's pitch (tilt) begins a change as + * the result of either user interaction or methods such as {@link Map#flyTo} . + */ + pitchstart: MapLibreEvent; + /** + * Fired repeatedly during the map's pitch (tilt) animation between + * one state and another as the result of either user interaction + * or methods such as {@link Map#flyTo}. + */ + pitch: MapLibreEvent; + /** + * Fired immediately after the map's pitch (tilt) finishes changing as + * the result of either user interaction or methods such as {@link Map#flyTo}. + */ + pitchend: MapLibreEvent; + /** + * Fired when a [`wheel`](https://developer.mozilla.org/en-US/docs/Web/Events/wheel) event occurs within the map. + */ + wheel: MapWheelEvent; +}; + +/** + * The base event for MapLibre + * + * @group Event Related + */ +export type MapLibreEvent = { + type: keyof MapEventType; + target: Map; + originalEvent: TOrig; +}; + +/** + * `MapMouseEvent` is the event type for mouse-related map events. + * + * @group Event Related + * + * @example + * ```ts + * // The `click` event is an example of a `MapMouseEvent`. + * // Set up an event listener on the map. + * map.on('click', (e) => { + * // The event object (e) contains information like the + * // coordinates of the point on the map that was clicked. + * console.log('A click event has occurred at ' + e.lngLat); + * }); + * ``` + */ +export class MapMouseEvent extends Event implements MapLibreEvent { + /** + * The event type + */ + public declare type: + | 'mousedown' + | 'mouseup' + | 'click' + | 'dblclick' + | 'mousemove' + | 'mouseover' + | 'mouseout' + | 'contextmenu'; + + /** + * The `Map` object that fired the event. + */ + target: Map; + + /** + * The DOM event which caused the map event. + */ + originalEvent: MouseEvent; + + /** + * The pixel coordinates of the mouse cursor, relative to the map and measured from the top left corner. + */ + point: Point; + + /** + * The geographic location on the map of the mouse cursor. + */ + lngLat: LngLat; + + /** + * Prevents subsequent default processing of the event by the map. + * + * Calling this method will prevent the following default map behaviors: + * + * * On `mousedown` events, the behavior of {@link DragPanHandler} + * * On `mousedown` events, the behavior of {@link DragRotateHandler} + * * On `mousedown` events, the behavior of {@link BoxZoomHandler} + * * On `dblclick` events, the behavior of {@link DoubleClickZoomHandler} + * + */ + preventDefault() { + this._defaultPrevented = true; + } + + /** + * `true` if `preventDefault` has been called. + */ + get defaultPrevented(): boolean { + return this._defaultPrevented; + } + + _defaultPrevented: boolean; + + constructor(type: string, map: Map, originalEvent: MouseEvent, data: any = {}) { + super(type, data); + const point = DOM.mousePos(map.getCanvasContainer(), originalEvent); + const lngLat = map.unproject(point); + this.point = point; + this.lngLat = lngLat; + this.originalEvent = originalEvent; + this._defaultPrevented = false; + this.target = map; + } +} + +/** + * `MapTouchEvent` is the event type for touch-related map events. + * + * @group Event Related + */ +export class MapTouchEvent extends Event implements MapLibreEvent { + /** + * The event type. + */ + public declare type: 'touchstart' | 'touchmove' | 'touchend' | 'touchcancel'; + + /** + * The `Map` object that fired the event. + */ + target: Map; + + /** + * The DOM event which caused the map event. + */ + originalEvent: TouchEvent; + + /** + * The geographic location on the map of the center of the touch event points. + */ + lngLat: LngLat; + + /** + * The pixel coordinates of the center of the touch event points, relative to the map and measured from the top left + * corner. + */ + point: Point; + + /** + * The array of pixel coordinates corresponding to a + * [touch event's `touches`](https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/touches) property. + */ + points: Array; + + /** + * The geographical locations on the map corresponding to a + * [touch event's `touches`](https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/touches) property. + */ + lngLats: Array; + + /** + * Prevents subsequent default processing of the event by the map. + * + * Calling this method will prevent the following default map behaviors: + * + * * On `touchstart` events, the behavior of {@link DragPanHandler} + * * On `touchstart` events, the behavior of {@link TwoFingersTouchZoomRotateHandler} + * + */ + preventDefault() { + this._defaultPrevented = true; + } + + /** + * `true` if `preventDefault` has been called. + */ + get defaultPrevented(): boolean { + return this._defaultPrevented; + } + + _defaultPrevented: boolean; + + constructor(type: string, map: Map, originalEvent: TouchEvent) { + super(type); + const touches = type === 'touchend' ? originalEvent.changedTouches : originalEvent.touches; + const points = DOM.touchPos(map.getCanvasContainer(), touches); + const lngLats = points.map((t) => map.unproject(t)); + const point = points.reduce( + (prev, curr, i, arr) => { + return prev.add(curr.div(arr.length)); + }, + new Point(0, 0), + ); + const lngLat = map.unproject(point); + + this.target = map; + this.points = points; + this.point = point; + this.lngLats = lngLats; + this.lngLat = lngLat; + this.originalEvent = originalEvent; + this._defaultPrevented = false; + } +} + +/** + * `MapWheelEvent` is the event type for the `wheel` map event. + * + * @group Event Related + * + */ +export class MapWheelEvent extends Event { + /** + * The event type + */ + public declare type: 'wheel'; + /** + * The `Map` object that fired the event. + */ + target: Map; + + /** + * The DOM event which caused the map event. + */ + originalEvent: WheelEvent; + + /** + * Prevents subsequent default processing of the event by the map. + * + * Calling this method will prevent the behavior of {@link ScrollZoomHandler}. + */ + preventDefault() { + this._defaultPrevented = true; + } + + /** + * `true` if `preventDefault` has been called. + */ + get defaultPrevented(): boolean { + return this._defaultPrevented; + } + + _defaultPrevented: boolean; + + /** */ + constructor(type: string, map: Map, originalEvent: WheelEvent) { + super(type); + this.target = map; + this._defaultPrevented = false; + this.originalEvent = originalEvent; + } +} + +/** + * A `MapLibreZoomEvent` is the event type for the boxzoom-related map events emitted by the {@link BoxZoomHandler}. + * + * @group Event Related + */ +export type MapLibreZoomEvent = { + /** + * The type of boxzoom event. One of `boxzoomstart`, `boxzoomend` or `boxzoomcancel` + */ + type: 'boxzoomstart' | 'boxzoomend' | 'boxzoomcancel'; + /** + * The `Map` instance that triggered the event + */ + target: Map; + /** + * The DOM event that triggered the boxzoom event. Can be a `MouseEvent` or `KeyboardEvent` + */ + originalEvent: MouseEvent; +}; diff --git a/packages/map/src/map/geo/edge_insets.ts b/packages/map/src/map/geo/edge_insets.ts new file mode 100644 index 00000000000..ccc12eebaef --- /dev/null +++ b/packages/map/src/map/geo/edge_insets.ts @@ -0,0 +1,158 @@ +import Point from '@mapbox/point-geometry'; +import { clamp, interpolates } from '../util/util'; + +/** + * An `EdgeInset` object represents screen space padding applied to the edges of the viewport. + * This shifts the apprent center or the vanishing point of the map. This is useful for adding floating UI elements + * on top of the map and having the vanishing point shift as UI elements resize. + * + * @group Geography and Geometry + */ +export class EdgeInsets { + /** + * @defaultValue 0 + */ + top: number; + /** + * @defaultValue 0 + */ + bottom: number; + /** + * @defaultValue 0 + */ + left: number; + /** + * @defaultValue 0 + */ + right: number; + + constructor(top: number = 0, bottom: number = 0, left: number = 0, right: number = 0) { + if ( + isNaN(top) || + top < 0 || + isNaN(bottom) || + bottom < 0 || + isNaN(left) || + left < 0 || + isNaN(right) || + right < 0 + ) { + throw new Error( + 'Invalid value for edge-insets, top, bottom, left and right must all be numbers', + ); + } + + this.top = top; + this.bottom = bottom; + this.left = left; + this.right = right; + } + + /** + * Interpolates the inset in-place. + * This maintains the current inset value for any inset not present in `target`. + * @param start - interpolation start + * @param target - interpolation target + * @param t - interpolation step/weight + * @returns the insets + */ + interpolate(start: PaddingOptions | EdgeInsets, target: PaddingOptions, t: number): EdgeInsets { + if (target.top != null && start.top != null) + this.top = interpolates.number(start.top, target.top, t); + if (target.bottom != null && start.bottom != null) + this.bottom = interpolates.number(start.bottom, target.bottom, t); + if (target.left != null && start.left != null) + this.left = interpolates.number(start.left, target.left, t); + if (target.right != null && start.right != null) + this.right = interpolates.number(start.right, target.right, t); + + return this; + } + + /** + * Utility method that computes the new apprent center or vanishing point after applying insets. + * This is in pixels and with the top left being (0.0) and +y being downwards. + * + * @param width - the width + * @param height - the height + * @returns the point + */ + getCenter(width: number, height: number): Point { + // Clamp insets so they never overflow width/height and always calculate a valid center + const x = clamp((this.left + width - this.right) / 2, 0, width); + const y = clamp((this.top + height - this.bottom) / 2, 0, height); + + return new Point(x, y); + } + + equals(other: PaddingOptions): boolean { + return ( + this.top === other.top && + this.bottom === other.bottom && + this.left === other.left && + this.right === other.right + ); + } + + clone(): EdgeInsets { + return new EdgeInsets(this.top, this.bottom, this.left, this.right); + } + + /** + * Returns the current state as json, useful when you want to have a + * read-only representation of the inset. + * + * @returns state as json + */ + toJSON(): PaddingOptions { + return { + top: this.top, + bottom: this.bottom, + left: this.left, + right: this.right, + }; + } +} + +/** + * Options for setting padding on calls to methods such as {@link Map#fitBounds}, {@link Map#fitScreenCoordinates}, and {@link Map#setPadding}. Adjust these options to set the amount of padding in pixels added to the edges of the canvas. Set a uniform padding on all edges or individual values for each edge. All properties of this object must be + * non-negative integers. + * + * @group Geography and Geometry + * + * @example + * ```ts + * let bbox = [[-79, 43], [-73, 45]]; + * map.fitBounds(bbox, { + * padding: {top: 10, bottom:25, left: 15, right: 5} + * }); + * ``` + * + * @example + * ```ts + * let bbox = [[-79, 43], [-73, 45]]; + * map.fitBounds(bbox, { + * padding: 20 + * }); + * ``` + * @see [Fit to the bounds of a LineString](https://maplibre.org/maplibre-gl-js/docs/examples/zoomto-linestring/) + * @see [Fit a map to a bounding box](https://maplibre.org/maplibre-gl-js/docs/examples/fitbounds/) + */ +export type PaddingOptions = { + /** + * Padding in pixels from the top of the map canvas. + */ + top: number; + /** + * Padding in pixels from the bottom of the map canvas. + */ + bottom: number; + /** + * Padding in pixels from the left of the map canvas. + */ + right: number; + /** + * Padding in pixels from the right of the map canvas. + */ + left: number; +}; diff --git a/packages/map/src/map/geo/lng_lat.ts b/packages/map/src/map/geo/lng_lat.ts new file mode 100644 index 00000000000..a527ac19e2a --- /dev/null +++ b/packages/map/src/map/geo/lng_lat.ts @@ -0,0 +1,177 @@ +import { wrap } from '../util/util'; + +/* + * Approximate radius of the earth in meters. + * Uses the WGS-84 approximation. The radius at the equator is ~6378137 and at the poles is ~6356752. https://en.wikipedia.org/wiki/World_Geodetic_System#WGS84 + * 6371008.8 is one published "average radius" see https://en.wikipedia.org/wiki/Earth_radius#Mean_radius, or ftp://athena.fsv.cvut.cz/ZFG/grs80-Moritz.pdf p.4 + */ +export const earthRadius = 6371008.8; + +/** + * A {@link LngLat} object, an array of two numbers representing longitude and latitude, + * or an object with `lng` and `lat` or `lon` and `lat` properties. + * + * @group Geography and Geometry + * + * @example + * ```ts + * let v1 = new LngLat(-122.420679, 37.772537); + * let v2 = [-122.420679, 37.772537]; + * let v3 = {lon: -122.420679, lat: 37.772537}; + * ``` + */ +export type LngLatLike = + | LngLat + | { + lng: number; + lat: number; + } + | { + lon: number; + lat: number; + } + | [number, number]; + +/** + * A `LngLat` object represents a given longitude and latitude coordinate, measured in degrees. + * These coordinates are based on the [WGS84 (EPSG:4326) standard](https://en.wikipedia.org/wiki/World_Geodetic_System#WGS84). + * + * MapLibre GL JS uses longitude, latitude coordinate order (as opposed to latitude, longitude) to match the + * [GeoJSON specification](https://tools.ietf.org/html/rfc7946). + * + * Note that any MapLibre GL JS method that accepts a `LngLat` object as an argument or option + * can also accept an `Array` of two numbers and will perform an implicit conversion. + * This flexible type is documented as {@link LngLatLike}. + * + * @group Geography and Geometry + * + * @example + * ```ts + * let ll = new LngLat(-123.9749, 40.7736); + * ll.lng; // = -123.9749 + * ``` + * @see [Get coordinates of the mouse pointer](https://maplibre.org/maplibre-gl-js/docs/examples/mouse-position/) + * @see [Display a popup](https://maplibre.org/maplibre-gl-js/docs/examples/popup/) + * @see [Create a timeline animation](https://maplibre.org/maplibre-gl-js/docs/examples/timeline-animation/) + */ +export class LngLat { + lng: number; + lat: number; + + /** + * @param lng - Longitude, measured in degrees. + * @param lat - Latitude, measured in degrees. + */ + constructor(lng: number, lat: number) { + if (isNaN(lng) || isNaN(lat)) { + throw new Error(`Invalid LngLat object: (${lng}, ${lat})`); + } + this.lng = +lng; + this.lat = +lat; + if (this.lat > 90 || this.lat < -90) { + throw new Error('Invalid LngLat latitude value: must be between -90 and 90'); + } + } + + /** + * Returns a new `LngLat` object whose longitude is wrapped to the range (-180, 180). + * + * @returns The wrapped `LngLat` object. + * @example + * ```ts + * let ll = new LngLat(286.0251, 40.7736); + * let wrapped = ll.wrap(); + * wrapped.lng; // = -73.9749 + * ``` + */ + wrap() { + return new LngLat(wrap(this.lng, -180, 180), this.lat); + } + + /** + * Returns the coordinates represented as an array of two numbers. + * + * @returns The coordinates represented as an array of longitude and latitude. + * @example + * ```ts + * let ll = new LngLat(-73.9749, 40.7736); + * ll.toArray(); // = [-73.9749, 40.7736] + * ``` + */ + toArray(): [number, number] { + return [this.lng, this.lat]; + } + + /** + * Returns the coordinates represent as a string. + * + * @returns The coordinates represented as a string of the format `'LngLat(lng, lat)'`. + * @example + * ```ts + * let ll = new LngLat(-73.9749, 40.7736); + * ll.toString(); // = "LngLat(-73.9749, 40.7736)" + * ``` + */ + toString(): string { + return `LngLat(${this.lng}, ${this.lat})`; + } + + /** + * Returns the approximate distance between a pair of coordinates in meters + * Uses the Haversine Formula (from R.W. Sinnott, "Virtues of the Haversine", Sky and Telescope, vol. 68, no. 2, 1984, p. 159) + * + * @param lngLat - coordinates to compute the distance to + * @returns Distance in meters between the two coordinates. + * @example + * ```ts + * let new_york = new LngLat(-74.0060, 40.7128); + * let los_angeles = new LngLat(-118.2437, 34.0522); + * new_york.distanceTo(los_angeles); // = 3935751.690893987, "true distance" using a non-spherical approximation is ~3966km + * ``` + */ + distanceTo(lngLat: LngLat): number { + const rad = Math.PI / 180; + const lat1 = this.lat * rad; + const lat2 = lngLat.lat * rad; + const a = + Math.sin(lat1) * Math.sin(lat2) + + Math.cos(lat1) * Math.cos(lat2) * Math.cos((lngLat.lng - this.lng) * rad); + + const maxMeters = earthRadius * Math.acos(Math.min(a, 1)); + return maxMeters; + } + + /** + * Converts an array of two numbers or an object with `lng` and `lat` or `lon` and `lat` properties + * to a `LngLat` object. + * + * If a `LngLat` object is passed in, the function returns it unchanged. + * + * @param input - An array of two numbers or object to convert, or a `LngLat` object to return. + * @returns A new `LngLat` object, if a conversion occurred, or the original `LngLat` object. + * @example + * ```ts + * let arr = [-73.9749, 40.7736]; + * let ll = LngLat.convert(arr); + * ll; // = LngLat {lng: -73.9749, lat: 40.7736} + * ``` + */ + static convert(input: LngLatLike): LngLat { + if (input instanceof LngLat) { + return input; + } + if (Array.isArray(input) && (input.length === 2 || input.length === 3)) { + return new LngLat(Number(input[0]), Number(input[1])); + } + if (!Array.isArray(input) && typeof input === 'object' && input !== null) { + return new LngLat( + // flow can't refine this to have one of lng or lat, so we have to cast to any + Number('lng' in input ? (input as any).lng : (input as any).lon), + Number(input.lat), + ); + } + throw new Error( + '`LngLatLike` argument must be specified as a LngLat instance, an object {lng: , lat: }, an object {lon: , lat: }, or an array of [, ]', + ); + } +} diff --git a/packages/map/src/map/geo/lng_lat_bounds.ts b/packages/map/src/map/geo/lng_lat_bounds.ts new file mode 100644 index 00000000000..bbe185802fd --- /dev/null +++ b/packages/map/src/map/geo/lng_lat_bounds.ts @@ -0,0 +1,350 @@ +import type { LngLatLike } from './lng_lat'; +import { LngLat } from './lng_lat'; + +/** + * A {@link LngLatBounds} object, an array of {@link LngLatLike} objects in [sw, ne] order, + * or an array of numbers in [west, south, east, north] order. + * + * @group Geography and Geometry + * + * @example + * ```ts + * let v1 = new LngLatBounds( + * new LngLat(-73.9876, 40.7661), + * new LngLat(-73.9397, 40.8002) + * ); + * let v2 = new LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]) + * let v3 = [[-73.9876, 40.7661], [-73.9397, 40.8002]]; + * ``` + */ +export type LngLatBoundsLike = + | LngLatBounds + | [LngLatLike, LngLatLike] + | [number, number, number, number]; + +/** + * A `LngLatBounds` object represents a geographical bounding box, + * defined by its southwest and northeast points in longitude and latitude. + * + * If no arguments are provided to the constructor, a `null` bounding box is created. + * + * Note that any Mapbox GL method that accepts a `LngLatBounds` object as an argument or option + * can also accept an `Array` of two {@link LngLatLike} constructs and will perform an implicit conversion. + * This flexible type is documented as {@link LngLatBoundsLike}. + * + * @group Geography and Geometry + * + * @example + * ```ts + * let sw = new LngLat(-73.9876, 40.7661); + * let ne = new LngLat(-73.9397, 40.8002); + * let llb = new LngLatBounds(sw, ne); + * ``` + */ +export class LngLatBounds { + _ne: LngLat; + _sw: LngLat; + + /** + * @param sw - The southwest corner of the bounding box. + * OR array of 4 numbers in the order of west, south, east, north + * OR array of 2 LngLatLike: [sw,ne] + * @param ne - The northeast corner of the bounding box. + * @example + * ```ts + * let sw = new LngLat(-73.9876, 40.7661); + * let ne = new LngLat(-73.9397, 40.8002); + * let llb = new LngLatBounds(sw, ne); + * ``` + * OR + * ```ts + * let llb = new LngLatBounds([-73.9876, 40.7661, -73.9397, 40.8002]); + * ``` + * OR + * ```ts + * let llb = new LngLatBounds([sw, ne]); + * ``` + */ + constructor( + sw?: LngLatLike | [number, number, number, number] | [LngLatLike, LngLatLike], + ne?: LngLatLike, + ) { + if (!sw) { + // noop + } else if (ne) { + this.setSouthWest(sw).setNorthEast(ne); + } else if (Array.isArray(sw)) { + if (sw.length === 4) { + // 4 element array: west, south, east, north + this.setSouthWest([sw[0], sw[1]]).setNorthEast([sw[2], sw[3]]); + } else { + this.setSouthWest(sw[0] as LngLatLike).setNorthEast(sw[1] as LngLatLike); + } + } + } + + /** + * Set the northeast corner of the bounding box + * + * @param ne - a {@link LngLatLike} object describing the northeast corner of the bounding box. + */ + setNorthEast(ne: LngLatLike): this { + this._ne = ne instanceof LngLat ? new LngLat(ne.lng, ne.lat) : LngLat.convert(ne); + return this; + } + + /** + * Set the southwest corner of the bounding box + * + * @param sw - a {@link LngLatLike} object describing the southwest corner of the bounding box. + */ + setSouthWest(sw: LngLatLike): this { + this._sw = sw instanceof LngLat ? new LngLat(sw.lng, sw.lat) : LngLat.convert(sw); + return this; + } + + /** + * Extend the bounds to include a given LngLatLike or LngLatBoundsLike. + * + * @param obj - object to extend to + */ + extend(obj: LngLatLike | LngLatBoundsLike): this { + const sw = this._sw, + ne = this._ne; + let sw2, ne2; + + if (obj instanceof LngLat) { + sw2 = obj; + ne2 = obj; + } else if (obj instanceof LngLatBounds) { + sw2 = obj._sw; + ne2 = obj._ne; + + if (!sw2 || !ne2) return this; + } else { + if (Array.isArray(obj)) { + if (obj.length === 4 || (obj as any[]).every(Array.isArray)) { + const lngLatBoundsObj = obj as any as LngLatBoundsLike; + return this.extend(LngLatBounds.convert(lngLatBoundsObj)); + } else { + const lngLatObj = obj as any as LngLatLike; + return this.extend(LngLat.convert(lngLatObj)); + } + } else if (obj && ('lng' in obj || 'lon' in obj) && 'lat' in obj) { + return this.extend(LngLat.convert(obj)); + } + + return this; + } + + if (!sw && !ne) { + this._sw = new LngLat(sw2.lng, sw2.lat); + this._ne = new LngLat(ne2.lng, ne2.lat); + } else { + sw.lng = Math.min(sw2.lng, sw.lng); + sw.lat = Math.min(sw2.lat, sw.lat); + ne.lng = Math.max(ne2.lng, ne.lng); + ne.lat = Math.max(ne2.lat, ne.lat); + } + + return this; + } + + /** + * Returns the geographical coordinate equidistant from the bounding box's corners. + * + * @returns The bounding box's center. + * @example + * ```ts + * let llb = new LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]); + * llb.getCenter(); // = LngLat {lng: -73.96365, lat: 40.78315} + * ``` + */ + getCenter(): LngLat { + return new LngLat((this._sw.lng + this._ne.lng) / 2, (this._sw.lat + this._ne.lat) / 2); + } + + /** + * Returns the southwest corner of the bounding box. + * + * @returns The southwest corner of the bounding box. + */ + getSouthWest(): LngLat { + return this._sw; + } + + /** + * Returns the northeast corner of the bounding box. + * + * @returns The northeast corner of the bounding box. + */ + getNorthEast(): LngLat { + return this._ne; + } + + /** + * Returns the northwest corner of the bounding box. + * + * @returns The northwest corner of the bounding box. + */ + getNorthWest(): LngLat { + return new LngLat(this.getWest(), this.getNorth()); + } + + /** + * Returns the southeast corner of the bounding box. + * + * @returns The southeast corner of the bounding box. + */ + getSouthEast(): LngLat { + return new LngLat(this.getEast(), this.getSouth()); + } + + /** + * Returns the west edge of the bounding box. + * + * @returns The west edge of the bounding box. + */ + getWest(): number { + return this._sw.lng; + } + + /** + * Returns the south edge of the bounding box. + * + * @returns The south edge of the bounding box. + */ + getSouth(): number { + return this._sw.lat; + } + + /** + * Returns the east edge of the bounding box. + * + * @returns The east edge of the bounding box. + */ + getEast(): number { + return this._ne.lng; + } + + /** + * Returns the north edge of the bounding box. + * + * @returns The north edge of the bounding box. + */ + getNorth(): number { + return this._ne.lat; + } + + /** + * Returns the bounding box represented as an array. + * + * @returns The bounding box represented as an array, consisting of the + * southwest and northeast coordinates of the bounding represented as arrays of numbers. + * @example + * ```ts + * let llb = new LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]); + * llb.toArray(); // = [[-73.9876, 40.7661], [-73.9397, 40.8002]] + * ``` + */ + toArray() { + return [this._sw.toArray(), this._ne.toArray()]; + } + + /** + * Return the bounding box represented as a string. + * + * @returns The bounding box represents as a string of the format + * `'LngLatBounds(LngLat(lng, lat), LngLat(lng, lat))'`. + * @example + * ```ts + * let llb = new LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]); + * llb.toString(); // = "LngLatBounds(LngLat(-73.9876, 40.7661), LngLat(-73.9397, 40.8002))" + * ``` + */ + toString() { + return `LngLatBounds(${this._sw.toString()}, ${this._ne.toString()})`; + } + + /** + * Check if the bounding box is an empty/`null`-type box. + * + * @returns True if bounds have been defined, otherwise false. + */ + isEmpty() { + return !(this._sw && this._ne); + } + + /** + * Check if the point is within the bounding box. + * + * @param lnglat - geographic point to check against. + * @returns `true` if the point is within the bounding box. + * @example + * ```ts + * let llb = new LngLatBounds( + * new LngLat(-73.9876, 40.7661), + * new LngLat(-73.9397, 40.8002) + * ); + * + * let ll = new LngLat(-73.9567, 40.7789); + * + * console.log(llb.contains(ll)); // = true + * ``` + */ + contains(lnglat: LngLatLike) { + const { lng, lat } = LngLat.convert(lnglat); + + const containsLatitude = this._sw.lat <= lat && lat <= this._ne.lat; + let containsLongitude = this._sw.lng <= lng && lng <= this._ne.lng; + if (this._sw.lng > this._ne.lng) { + // wrapped coordinates + containsLongitude = this._sw.lng >= lng && lng >= this._ne.lng; + } + + return containsLatitude && containsLongitude; + } + + /** + * Converts an array to a `LngLatBounds` object. + * + * If a `LngLatBounds` object is passed in, the function returns it unchanged. + * + * Internally, the function calls `LngLat#convert` to convert arrays to `LngLat` values. + * + * @param input - An array of two coordinates to convert, or a `LngLatBounds` object to return. + * @returns A new `LngLatBounds` object, if a conversion occurred, or the original `LngLatBounds` object. + * @example + * ```ts + * let arr = [[-73.9876, 40.7661], [-73.9397, 40.8002]]; + * let llb = LngLatBounds.convert(arr); // = LngLatBounds {_sw: LngLat {lng: -73.9876, lat: 40.7661}, _ne: LngLat {lng: -73.9397, lat: 40.8002}} + * ``` + */ + static convert(input: LngLatBoundsLike): LngLatBounds { + if (input instanceof LngLatBounds) return input; + return new LngLatBounds(input); + } + + /** + * Returns a `LngLatBounds` from the coordinates extended by a given `radius`. The returned `LngLatBounds` completely contains the `radius`. + * + * @param center - center coordinates of the new bounds. + * @param radius - Distance in meters from the coordinates to extend the bounds. + * @returns A new `LngLatBounds` object representing the coordinates extended by the `radius`. + * @example + * ```ts + * let center = new LngLat(-73.9749, 40.7736); + * LngLatBounds.fromLngLat(100).toArray(); // = [[-73.97501862141328, 40.77351016847229], [-73.97478137858673, 40.77368983152771]] + * ``` + */ + static fromLngLat(center: LngLat, radius: number = 0): LngLatBounds { + const earthCircumferenceInMetersAtEquator = 40075017; + const latAccuracy = (360 * radius) / earthCircumferenceInMetersAtEquator, + lngAccuracy = latAccuracy / Math.cos((Math.PI / 180) * center.lat); + + return new LngLatBounds( + new LngLat(center.lng - lngAccuracy, center.lat - latAccuracy), + new LngLat(center.lng + lngAccuracy, center.lat + latAccuracy), + ); + } +} diff --git a/packages/map/src/map/geo/mercator_coordinate.ts b/packages/map/src/map/geo/mercator_coordinate.ts new file mode 100644 index 00000000000..a460d4957b5 --- /dev/null +++ b/packages/map/src/map/geo/mercator_coordinate.ts @@ -0,0 +1,173 @@ +import type { LngLatLike } from './lng_lat'; +import { LngLat, earthRadius } from './lng_lat'; + +interface ILngLat { + lng: number; + lat: number; + wrap(): ILngLat; + toArray(): [number, number]; + distanceTo(lngLat: ILngLat): number; + toString(): string; +} + +interface IMercatorCoordinate { + x: number; + y: number; + z: number; + toLngLat(): ILngLat; + toAltitude(): number; + meterInMercatorCoordinateUnits(): number; +} + +/* + * The average circumference of the world in meters. + */ +const earthCircumfrence = 2 * Math.PI * earthRadius; // meters + +/* + * The circumference at a line of latitude in meters. + */ +function circumferenceAtLatitude(latitude: number) { + return earthCircumfrence * Math.cos((latitude * Math.PI) / 180); +} + +export function mercatorXfromLng(lng: number) { + return (180 + lng) / 360; +} + +export function mercatorYfromLat(lat: number) { + return (180 - (180 / Math.PI) * Math.log(Math.tan(Math.PI / 4 + (lat * Math.PI) / 360))) / 360; +} + +export function mercatorZfromAltitude(altitude: number, lat: number) { + return altitude / circumferenceAtLatitude(lat); +} + +export function lngFromMercatorX(x: number) { + return x * 360 - 180; +} + +export function latFromMercatorY(y: number) { + const y2 = 180 - y * 360; + return (360 / Math.PI) * Math.atan(Math.exp((y2 * Math.PI) / 180)) - 90; +} + +export function altitudeFromMercatorZ(z: number, y: number) { + return z * circumferenceAtLatitude(latFromMercatorY(y)); +} + +/** + * Determine the Mercator scale factor for a given latitude, see + * https://en.wikipedia.org/wiki/Mercator_projection#Scale_factor + * + * At the equator the scale factor will be 1, which increases at higher latitudes. + * + * @param lat - Latitude + * @returns scale factor + */ +export function mercatorScale(lat: number) { + return 1 / Math.cos((lat * Math.PI) / 180); +} + +/** + * A `MercatorCoordinate` object represents a projected three dimensional position. + * + * `MercatorCoordinate` uses the web mercator projection ([EPSG:3857](https://epsg.io/3857)) with slightly different units: + * + * - the size of 1 unit is the width of the projected world instead of the "mercator meter" + * - the origin of the coordinate space is at the north-west corner instead of the middle + * + * For example, `MercatorCoordinate(0, 0, 0)` is the north-west corner of the mercator world and + * `MercatorCoordinate(1, 1, 0)` is the south-east corner. If you are familiar with + * [vector tiles](https://github.com/mapbox/vector-tile-spec) it may be helpful to think + * of the coordinate space as the `0/0/0` tile with an extent of `1`. + * + * The `z` dimension of `MercatorCoordinate` is conformal. A cube in the mercator coordinate space would be rendered as a cube. + * + * @group Geography and Geometry + * + * @example + * ```ts + * let nullIsland = new MercatorCoordinate(0.5, 0.5, 0); + * ``` + * @see [Add a custom style layer](https://maplibre.org/maplibre-gl-js/docs/examples/custom-style-layer/) + */ +export class MercatorCoordinate implements IMercatorCoordinate { + x: number; + y: number; + z: number; + + /** + * @param x - The x component of the position. + * @param y - The y component of the position. + * @param z - The z component of the position. + */ + constructor(x: number, y: number, z: number = 0) { + this.x = +x; + this.y = +y; + this.z = +z; + } + + /** + * Project a `LngLat` to a `MercatorCoordinate`. + * + * @param lngLatLike - The location to project. + * @param altitude - The altitude in meters of the position. + * @returns The projected mercator coordinate. + * @example + * ```ts + * let coord = MercatorCoordinate.fromLngLat({ lng: 0, lat: 0}, 0); + * coord; // MercatorCoordinate(0.5, 0.5, 0) + * ``` + */ + static fromLngLat(lngLatLike: LngLatLike, altitude: number = 0): MercatorCoordinate { + const lngLat = LngLat.convert(lngLatLike); + + return new MercatorCoordinate( + mercatorXfromLng(lngLat.lng), + mercatorYfromLat(lngLat.lat), + mercatorZfromAltitude(altitude, lngLat.lat), + ); + } + + /** + * Returns the `LngLat` for the coordinate. + * + * @returns The `LngLat` object. + * @example + * ```ts + * let coord = new MercatorCoordinate(0.5, 0.5, 0); + * let lngLat = coord.toLngLat(); // LngLat(0, 0) + * ``` + */ + toLngLat() { + return new LngLat(lngFromMercatorX(this.x), latFromMercatorY(this.y)); + } + + /** + * Returns the altitude in meters of the coordinate. + * + * @returns The altitude in meters. + * @example + * ```ts + * let coord = new MercatorCoordinate(0, 0, 0.02); + * coord.toAltitude(); // 6914.281956295339 + * ``` + */ + toAltitude(): number { + return altitudeFromMercatorZ(this.z, this.y); + } + + /** + * Returns the distance of 1 meter in `MercatorCoordinate` units at this latitude. + * + * For coordinates in real world units using meters, this naturally provides the scale + * to transform into `MercatorCoordinate`s. + * + * @returns Distance of 1 meter in `MercatorCoordinate` units. + */ + meterInMercatorCoordinateUnits(): number { + // 1 meter / circumference at equator in meters * Mercator projection scale factor at this latitude + return (1 / earthCircumfrence) * mercatorScale(latFromMercatorY(this.y)); + } +} diff --git a/packages/map/src/map/geo/transform.ts b/packages/map/src/map/geo/transform.ts new file mode 100644 index 00000000000..f8a2eaccf29 --- /dev/null +++ b/packages/map/src/map/geo/transform.ts @@ -0,0 +1,849 @@ +import Point from '@mapbox/point-geometry'; +import { mat2, mat4, vec4 } from 'gl-matrix'; +import { clamp, interpolates, wrap } from '../util/util'; +import { EdgeInsets } from './edge_insets'; +import { LngLat } from './lng_lat'; +import { LngLatBounds } from './lng_lat_bounds'; +import { + MercatorCoordinate, + mercatorXfromLng, + mercatorYfromLat, + mercatorZfromAltitude, +} from './mercator_coordinate'; + +import type { PaddingOptions } from './edge_insets'; + +export const MAX_VALID_LATITUDE = 85.051129; + +/** + * @internal + * A single transform, generally used for a single tile to be + * scaled, rotated, and zoomed. + */ +export class Transform { + tileSize: number; + tileZoom: number; + lngRange: [number, number]; + latRange: [number, number]; + scale: number; + width: number; + height: number; + angle: number; + rotationMatrix: mat2; + pixelsToGLUnits: [number, number]; + cameraToCenterDistance: number; + mercatorMatrix: mat4; + projMatrix: mat4; + invProjMatrix: mat4; + alignedProjMatrix: mat4; + pixelMatrix: mat4; + pixelMatrix3D: mat4; + pixelMatrixInverse: mat4; + glCoordMatrix: mat4; + labelPlaneMatrix: mat4; + minElevationForCurrentTile: number; + _fov: number; + _pitch: number; + _zoom: number; + _unmodified: boolean; + _renderWorldCopies: boolean; + _minZoom: number; + _maxZoom: number; + _minPitch: number; + _maxPitch: number; + _center: LngLat; + _elevation: number; + _pixelPerMeter: number; + _edgeInsets: EdgeInsets; + _constraining: boolean; + _posMatrixCache: { [_: string]: mat4 }; + _alignedPosMatrixCache: { [_: string]: mat4 }; + + constructor( + minZoom?: number, + maxZoom?: number, + minPitch?: number, + maxPitch?: number, + renderWorldCopies?: boolean, + ) { + this.tileSize = 512; // constant + + this._renderWorldCopies = renderWorldCopies === undefined ? true : !!renderWorldCopies; + this._minZoom = minZoom || 0; + this._maxZoom = maxZoom || 22; + + this._minPitch = minPitch === undefined || minPitch === null ? 0 : minPitch; + this._maxPitch = maxPitch === undefined || maxPitch === null ? 60 : maxPitch; + + this.setMaxBounds(); + + this.width = 0; + this.height = 0; + this._center = new LngLat(0, 0); + this._elevation = 0; + this.zoom = 0; + this.angle = 0; + this._fov = 0.6435011087932844; + this._pitch = 0; + this._unmodified = true; + this._edgeInsets = new EdgeInsets(); + this._posMatrixCache = {}; + this._alignedPosMatrixCache = {}; + this.minElevationForCurrentTile = 0; + } + + clone(): Transform { + const clone = new Transform( + this._minZoom, + this._maxZoom, + this._minPitch, + this.maxPitch, + this._renderWorldCopies, + ); + clone.apply(this); + return clone; + } + + apply(that: Transform) { + this.tileSize = that.tileSize; + this.latRange = that.latRange; + this.width = that.width; + this.height = that.height; + this._center = that._center; + this._elevation = that._elevation; + this.minElevationForCurrentTile = that.minElevationForCurrentTile; + this.zoom = that.zoom; + this.angle = that.angle; + this._fov = that._fov; + this._pitch = that._pitch; + this._unmodified = that._unmodified; + this._edgeInsets = that._edgeInsets.clone(); + this._calcMatrices(); + } + + get minZoom(): number { + return this._minZoom; + } + set minZoom(zoom: number) { + if (this._minZoom === zoom) return; + this._minZoom = zoom; + this.zoom = Math.max(this.zoom, zoom); + } + + get maxZoom(): number { + return this._maxZoom; + } + set maxZoom(zoom: number) { + if (this._maxZoom === zoom) return; + this._maxZoom = zoom; + this.zoom = Math.min(this.zoom, zoom); + } + + get minPitch(): number { + return this._minPitch; + } + set minPitch(pitch: number) { + if (this._minPitch === pitch) return; + this._minPitch = pitch; + this.pitch = Math.max(this.pitch, pitch); + } + + get maxPitch(): number { + return this._maxPitch; + } + set maxPitch(pitch: number) { + if (this._maxPitch === pitch) return; + this._maxPitch = pitch; + this.pitch = Math.min(this.pitch, pitch); + } + + get renderWorldCopies(): boolean { + return this._renderWorldCopies; + } + set renderWorldCopies(renderWorldCopies: boolean | null | undefined) { + if (renderWorldCopies === undefined) { + renderWorldCopies = true; + } else if (renderWorldCopies === null) { + renderWorldCopies = false; + } + + this._renderWorldCopies = renderWorldCopies; + } + + get worldSize(): number { + return this.tileSize * this.scale; + } + + get centerOffset(): Point { + return this.centerPoint._sub(this.size._div(2)); + } + + get size(): Point { + return new Point(this.width, this.height); + } + + get bearing(): number { + return (-this.angle / Math.PI) * 180; + } + set bearing(bearing: number) { + const b = (-wrap(bearing, -180, 180) * Math.PI) / 180; + if (this.angle === b) return; + this._unmodified = false; + this.angle = b; + this._calcMatrices(); + + // 2x2 matrix for rotating points + this.rotationMatrix = mat2.create(); + mat2.rotate(this.rotationMatrix, this.rotationMatrix, this.angle); + } + + get pitch(): number { + return (this._pitch / Math.PI) * 180; + } + set pitch(pitch: number) { + const p = (clamp(pitch, this.minPitch, this.maxPitch) / 180) * Math.PI; + if (this._pitch === p) return; + this._unmodified = false; + this._pitch = p; + this._calcMatrices(); + } + + get fov(): number { + return (this._fov / Math.PI) * 180; + } + set fov(fov: number) { + fov = Math.max(0.01, Math.min(60, fov)); + if (this._fov === fov) return; + this._unmodified = false; + this._fov = (fov / 180) * Math.PI; + this._calcMatrices(); + } + + get zoom(): number { + return this._zoom; + } + set zoom(zoom: number) { + const constrainedZoom = Math.min(Math.max(zoom, this.minZoom), this.maxZoom); + if (this._zoom === constrainedZoom) return; + this._unmodified = false; + this._zoom = constrainedZoom; + this.tileZoom = Math.max(0, Math.floor(constrainedZoom)); + this.scale = this.zoomScale(constrainedZoom); + this._constrain(); + this._calcMatrices(); + } + + get center(): LngLat { + return this._center; + } + set center(center: LngLat) { + if (center.lat === this._center.lat && center.lng === this._center.lng) return; + this._unmodified = false; + this._center = center; + this._constrain(); + this._calcMatrices(); + } + + /** + * Elevation at current center point, meters above sea level + */ + get elevation(): number { + return this._elevation; + } + set elevation(elevation: number) { + if (elevation === this._elevation) return; + this._elevation = elevation; + this._constrain(); + this._calcMatrices(); + } + + get padding(): PaddingOptions { + return this._edgeInsets.toJSON(); + } + set padding(padding: PaddingOptions) { + if (this._edgeInsets.equals(padding)) return; + this._unmodified = false; + //Update edge-insets inplace + this._edgeInsets.interpolate(this._edgeInsets, padding, 1); + this._calcMatrices(); + } + + /** + * The center of the screen in pixels with the top-left corner being (0,0) + * and +y axis pointing downwards. This accounts for padding. + */ + get centerPoint(): Point { + return this._edgeInsets.getCenter(this.width, this.height); + } + + /** + * Returns if the padding params match + * + * @param padding - the padding to check against + * @returns true if they are equal, false otherwise + */ + isPaddingEqual(padding: PaddingOptions): boolean { + return this._edgeInsets.equals(padding); + } + + /** + * Helper method to update edge-insets in place + * + * @param start - the starting padding + * @param target - the target padding + * @param t - the step/weight + */ + interpolatePadding(start: PaddingOptions, target: PaddingOptions, t: number) { + this._unmodified = false; + this._edgeInsets.interpolate(start, target, t); + this._constrain(); + this._calcMatrices(); + } + + /** + * Return a zoom level that will cover all tiles the transform + * @param options - the options + * @returns zoom level An integer zoom level at which all tiles will be visible. + */ + coveringZoomLevel(options: { + /** + * Target zoom level. If true, the value will be rounded to the closest integer. Otherwise the value will be floored. + */ + roundZoom?: boolean; + /** + * Tile size, expressed in screen pixels. + */ + tileSize: number; + }): number { + const z = (options.roundZoom ? Math.round : Math.floor)( + this.zoom + this.scaleZoom(this.tileSize / options.tileSize), + ); + // At negative zoom levels load tiles from z0 because negative tile zoom levels don't exist. + return Math.max(0, z); + } + + resize(width: number, height: number) { + this.width = width; + this.height = height; + + this.pixelsToGLUnits = [2 / width, -2 / height]; + this._constrain(); + this._calcMatrices(); + } + + get unmodified(): boolean { + return this._unmodified; + } + + zoomScale(zoom: number) { + return Math.pow(2, zoom); + } + scaleZoom(scale: number) { + return Math.log(scale) / Math.LN2; + } + + /** + * Convert from LngLat to world coordinates (Mercator coordinates scaled by 512) + * @param lnglat - the lngLat + * @returns Point + */ + project(lnglat: LngLat) { + const lat = clamp(lnglat.lat, -MAX_VALID_LATITUDE, MAX_VALID_LATITUDE); + return new Point( + mercatorXfromLng(lnglat.lng) * this.worldSize, + mercatorYfromLat(lat) * this.worldSize, + ); + } + + /** + * Convert from world coordinates ([0, 512],[0, 512]) to LngLat ([-180, 180], [-90, 90]) + * @param point - world coordinate + * @returns LngLat + */ + unproject(point: Point): LngLat { + return new MercatorCoordinate(point.x / this.worldSize, point.y / this.worldSize).toLngLat(); + } + + get point(): Point { + return this.project(this.center); + } + + /** + * get the camera position in LngLat and altitudes in meter + * @returns An object with lngLat & altitude. + */ + getCameraPosition(): { + lngLat: LngLat; + altitude: number; + } { + const lngLat = this.pointLocation(this.getCameraPoint()); + const altitude = (Math.cos(this._pitch) * this.cameraToCenterDistance) / this._pixelPerMeter; + return { lngLat, altitude: altitude + this.elevation }; + } + + setLocationAtPoint(lnglat: LngLat, point: Point) { + const a = this.pointCoordinate(point); + const b = this.pointCoordinate(this.centerPoint); + const loc = this.locationCoordinate(lnglat); + const newCenter = new MercatorCoordinate(loc.x - (a.x - b.x), loc.y - (a.y - b.y)); + this.center = this.coordinateLocation(newCenter); + if (this._renderWorldCopies) { + this.center = this.center.wrap(); + } + } + + /** + * Given a LngLat location, return the screen point that corresponds to it + * @param lnglat - location + * @param terrain - optional terrain + * @returns screen point + */ + locationPoint(lnglat: LngLat): Point { + return this.coordinatePoint(this.locationCoordinate(lnglat)); + } + + /** + * Given a point on screen, return its lnglat + * @param p - screen point + * @param terrain - optional terrain + * @returns lnglat location + */ + pointLocation(p: Point): LngLat { + return this.coordinateLocation(this.pointCoordinate(p)); + } + + /** + * Given a geographical lnglat, return an unrounded + * coordinate that represents it at low zoom level. + * @param lnglat - the location + * @returns The mercator coordinate + */ + locationCoordinate(lnglat: LngLat): MercatorCoordinate { + return MercatorCoordinate.fromLngLat(lnglat); + } + + /** + * Given a Coordinate, return its geographical position. + * @param coord - mercator coordinates + * @returns lng and lat + */ + coordinateLocation(coord: MercatorCoordinate): LngLat { + return coord && coord.toLngLat(); + } + + /** + * Given a Point, return its mercator coordinate. + * @param p - the point + * @param terrain - optional terrain + * @returns lnglat + */ + pointCoordinate(p: Point): MercatorCoordinate { + // calculate point-coordinate on flat earth + const targetZ = 0; + // since we don't know the correct projected z value for the point, + // unproject two points to get a line and then find the point on that + // line with z=0 + + const coord0 = [p.x, p.y, 0, 1] as vec4; + const coord1 = [p.x, p.y, 1, 1] as vec4; + + vec4.transformMat4(coord0, coord0, this.pixelMatrixInverse); + vec4.transformMat4(coord1, coord1, this.pixelMatrixInverse); + + const w0 = coord0[3]; + const w1 = coord1[3]; + const x0 = coord0[0] / w0; + const x1 = coord1[0] / w1; + const y0 = coord0[1] / w0; + const y1 = coord1[1] / w1; + const z0 = coord0[2] / w0; + const z1 = coord1[2] / w1; + + const t = z0 === z1 ? 0 : (targetZ - z0) / (z1 - z0); + + return new MercatorCoordinate( + interpolates.number(x0, x1, t) / this.worldSize, + interpolates.number(y0, y1, t) / this.worldSize, + ); + } + + /** + * Given a coordinate, return the screen point that corresponds to it + * @param coord - the coordinates + * @param elevation - the elevation + * @param pixelMatrix - the pixel matrix + * @returns screen point + */ + coordinatePoint( + coord: MercatorCoordinate, + elevation: number = 0, + pixelMatrix = this.pixelMatrix, + ): Point { + const p = [coord.x * this.worldSize, coord.y * this.worldSize, elevation, 1] as vec4; + vec4.transformMat4(p, p, pixelMatrix); + return new Point(p[0] / p[3], p[1] / p[3]); + } + + /** + * Returns the map's geographical bounds. When the bearing or pitch is non-zero, the visible region is not + * an axis-aligned rectangle, and the result is the smallest bounds that encompasses the visible region. + * @returns Returns a {@link LngLatBounds} object describing the map's geographical bounds. + */ + getBounds(): LngLatBounds { + const top = Math.max(0, this.height / 2 - this.getHorizon()); + return new LngLatBounds() + .extend(this.pointLocation(new Point(0, top))) + .extend(this.pointLocation(new Point(this.width, top))) + .extend(this.pointLocation(new Point(this.width, this.height))) + .extend(this.pointLocation(new Point(0, this.height))); + } + + /** + * Returns the maximum geographical bounds the map is constrained to, or `null` if none set. + * @returns max bounds + */ + getMaxBounds(): LngLatBounds | null { + if ( + !this.latRange || + this.latRange.length !== 2 || + !this.lngRange || + this.lngRange.length !== 2 + ) + return null; + + return new LngLatBounds( + [this.lngRange[0], this.latRange[0]], + [this.lngRange[1], this.latRange[1]], + ); + } + + /** + * Calculate pixel height of the visible horizon in relation to map-center (e.g. height/2), + * multiplied by a static factor to simulate the earth-radius. + * The calculated value is the horizontal line from the camera-height to sea-level. + * @returns Horizon above center in pixels. + */ + getHorizon(): number { + return Math.tan(Math.PI / 2 - this._pitch) * this.cameraToCenterDistance * 0.85; + } + + /** + * Sets or clears the map's geographical constraints. + * @param bounds - A {@link LngLatBounds} object describing the new geographic boundaries of the map. + */ + setMaxBounds(bounds?: LngLatBounds | null) { + if (bounds) { + this.lngRange = [bounds.getWest(), bounds.getEast()]; + this.latRange = [bounds.getSouth(), bounds.getNorth()]; + this._constrain(); + } else { + this.lngRange = null; + this.latRange = [-MAX_VALID_LATITUDE, MAX_VALID_LATITUDE]; + } + } + + customLayerMatrix(): mat4 { + return this.mercatorMatrix.slice() as any; + } + + /** + * Get center lngLat and zoom to ensure that + * 1) everything beyond the bounds is excluded + * 2) a given lngLat is as near the center as possible + * Bounds are those set by maxBounds or North & South "Poles" and, if only 1 globe is displayed, antimeridian. + */ + getConstrained(lngLat: LngLat, zoom: number): { center: LngLat; zoom: number } { + zoom = clamp(+zoom, this.minZoom, this.maxZoom); + const result = { + center: new LngLat(lngLat.lng, lngLat.lat), + zoom, + }; + + let lngRange = this.lngRange; + + if (!this._renderWorldCopies && lngRange === null) { + const almost180 = 180 - 1e-10; + lngRange = [-almost180, almost180]; + } + + const worldSize = this.tileSize * this.zoomScale(result.zoom); // A world size for the requested zoom level, not the current world size + let minY = 0; + let maxY = worldSize; + let minX = 0; + let maxX = worldSize; + let scaleY = 0; + let scaleX = 0; + const { x: screenWidth, y: screenHeight } = this.size; + + if (this.latRange) { + const latRange = this.latRange; + minY = mercatorYfromLat(latRange[1]) * worldSize; + maxY = mercatorYfromLat(latRange[0]) * worldSize; + const shouldZoomIn = maxY - minY < screenHeight; + if (shouldZoomIn) scaleY = screenHeight / (maxY - minY); + } + + if (lngRange) { + minX = wrap(mercatorXfromLng(lngRange[0]) * worldSize, 0, worldSize); + maxX = wrap(mercatorXfromLng(lngRange[1]) * worldSize, 0, worldSize); + + if (maxX < minX) maxX += worldSize; + + const shouldZoomIn = maxX - minX < screenWidth; + if (shouldZoomIn) scaleX = screenWidth / (maxX - minX); + } + + const { x: originalX, y: originalY } = this.project.call({ worldSize }, lngLat); + let modifiedX, modifiedY; + + const scale = Math.max(scaleX || 0, scaleY || 0); + + if (scale) { + // zoom in to exclude all beyond the given lng/lat ranges + const newPoint = new Point( + scaleX ? (maxX + minX) / 2 : originalX, + scaleY ? (maxY + minY) / 2 : originalY, + ); + result.center = this.unproject.call({ worldSize }, newPoint).wrap(); + result.zoom += this.scaleZoom(scale); + return result; + } + + if (this.latRange) { + const h2 = screenHeight / 2; + if (originalY - h2 < minY) modifiedY = minY + h2; + if (originalY + h2 > maxY) modifiedY = maxY - h2; + } + + if (lngRange) { + const centerX = (minX + maxX) / 2; + let wrappedX = originalX; + if (this._renderWorldCopies) { + wrappedX = wrap(originalX, centerX - worldSize / 2, centerX + worldSize / 2); + } + const w2 = screenWidth / 2; + + if (wrappedX - w2 < minX) modifiedX = minX + w2; + if (wrappedX + w2 > maxX) modifiedX = maxX - w2; + } + + // pan the map if the screen goes off the range + if (modifiedX !== undefined || modifiedY !== undefined) { + const newPoint = new Point(modifiedX ?? originalX, modifiedY ?? originalY); + result.center = this.unproject.call({ worldSize }, newPoint).wrap(); + } + + return result; + } + + _constrain() { + if (!this.center || !this.width || !this.height || this._constraining) return; + this._constraining = true; + const unmodified = this._unmodified; + const { center, zoom } = this.getConstrained(this.center, this.zoom); + this.center = center; + this.zoom = zoom; + this._unmodified = unmodified; + this._constraining = false; + } + + _calcMatrices() { + if (!this.height) return; + + const halfFov = this._fov / 2; + const offset = this.centerOffset; + const x = this.point.x, + y = this.point.y; + this.cameraToCenterDistance = (0.5 / Math.tan(halfFov)) * this.height; + this._pixelPerMeter = mercatorZfromAltitude(1, this.center.lat) * this.worldSize; + + let m = mat4.identity(new Float64Array(16) as any); + mat4.scale(m, m, [this.width / 2, -this.height / 2, 1]); + mat4.translate(m, m, [1, -1, 0]); + this.labelPlaneMatrix = m; + + m = mat4.identity(new Float64Array(16) as any); + mat4.scale(m, m, [1, -1, 1]); + mat4.translate(m, m, [-1, -1, 0]); + mat4.scale(m, m, [2 / this.width, 2 / this.height, 1]); + this.glCoordMatrix = m; + + // Calculate the camera to sea-level distance in pixel in respect of terrain + const cameraToSeaLevelDistance = + this.cameraToCenterDistance + (this._elevation * this._pixelPerMeter) / Math.cos(this._pitch); + // In case of negative minimum elevation (e.g. the dead see, under the sea maps) use a lower plane for calculation + const minElevation = Math.min(this.elevation, this.minElevationForCurrentTile); + const cameraToLowestPointDistance = + cameraToSeaLevelDistance - (minElevation * this._pixelPerMeter) / Math.cos(this._pitch); + const lowestPlane = minElevation < 0 ? cameraToLowestPointDistance : cameraToSeaLevelDistance; + + // Find the distance from the center point [width/2 + offset.x, height/2 + offset.y] to the + // center top point [width/2 + offset.x, 0] in Z units, using the law of sines. + // 1 Z unit is equivalent to 1 horizontal px at the center of the map + // (the distance between[width/2, height/2] and [width/2 + 1, height/2]) + const groundAngle = Math.PI / 2 + this._pitch; + const fovAboveCenter = this._fov * (0.5 + offset.y / this.height); + const topHalfSurfaceDistance = + (Math.sin(fovAboveCenter) * lowestPlane) / + Math.sin(clamp(Math.PI - groundAngle - fovAboveCenter, 0.01, Math.PI - 0.01)); + + // Find the distance from the center point to the horizon + const horizon = this.getHorizon(); + const horizonAngle = Math.atan(horizon / this.cameraToCenterDistance); + const fovCenterToHorizon = 2 * horizonAngle * (0.5 + offset.y / (horizon * 2)); + const topHalfSurfaceDistanceHorizon = + (Math.sin(fovCenterToHorizon) * lowestPlane) / + Math.sin(clamp(Math.PI - groundAngle - fovCenterToHorizon, 0.01, Math.PI - 0.01)); + + // Calculate z distance of the farthest fragment that should be rendered. + // Add a bit extra to avoid precision problems when a fragment's distance is exactly `furthestDistance` + const topHalfMinDistance = Math.min(topHalfSurfaceDistance, topHalfSurfaceDistanceHorizon); + const farZ = (Math.cos(Math.PI / 2 - this._pitch) * topHalfMinDistance + lowestPlane) * 1.01; + + // The larger the value of nearZ is + // - the more depth precision is available for features (good) + // - clipping starts appearing sooner when the camera is close to 3d features (bad) + // + // Other values work for mapbox-gl-js but deckgl was encountering precision issues + // when rendering custom layers. This value was experimentally chosen and + // seems to solve z-fighting issues in deckgl while not clipping buildings too close to the camera. + const nearZ = this.height / 50; + + // matrix for conversion from location to clip space(-1 .. 1) + m = new Float64Array(16) as any; + mat4.perspective(m, this._fov, this.width / this.height, nearZ, farZ); + + // Apply center of perspective offset + m[8] = (-offset.x * 2) / this.width; + m[9] = (offset.y * 2) / this.height; + + mat4.scale(m, m, [1, -1, 1]); + mat4.translate(m, m, [0, 0, -this.cameraToCenterDistance]); + mat4.rotateX(m, m, this._pitch); + mat4.rotateZ(m, m, this.angle); + mat4.translate(m, m, [-x, -y, 0]); + + // The mercatorMatrix can be used to transform points from mercator coordinates + // ([0, 0] nw, [1, 1] se) to clip space. + this.mercatorMatrix = mat4.scale([] as any, m, [ + this.worldSize, + this.worldSize, + this.worldSize, + ]); + + // scale vertically to meters per pixel (inverse of ground resolution): + mat4.scale(m, m, [1, 1, this._pixelPerMeter]); + + // matrix for conversion from world space to screen coordinates in 2D + this.pixelMatrix = mat4.multiply(new Float64Array(16) as any, this.labelPlaneMatrix, m); + + // matrix for conversion from world space to clip space (-1 .. 1) + mat4.translate(m, m, [0, 0, -this.elevation]); // elevate camera over terrain + this.projMatrix = m; + this.invProjMatrix = mat4.invert([] as any, m); + + // matrix for conversion from world space to screen coordinates in 3D + this.pixelMatrix3D = mat4.multiply(new Float64Array(16) as any, this.labelPlaneMatrix, m); + + // Make a second projection matrix that is aligned to a pixel grid for rendering raster tiles. + // We're rounding the (floating point) x/y values to achieve to avoid rendering raster images to fractional + // coordinates. Additionally, we adjust by half a pixel in either direction in case that viewport dimension + // is an odd integer to preserve rendering to the pixel grid. We're rotating this shift based on the angle + // of the transformation so that 0°, 90°, 180°, and 270° rasters are crisp, and adjust the shift so that + // it is always <= 0.5 pixels. + const xShift = (this.width % 2) / 2, + yShift = (this.height % 2) / 2, + angleCos = Math.cos(this.angle), + angleSin = Math.sin(this.angle), + dx = x - Math.round(x) + angleCos * xShift + angleSin * yShift, + dy = y - Math.round(y) + angleCos * yShift + angleSin * xShift; + const alignedM = new Float64Array(m) as any as mat4; + mat4.translate(alignedM, alignedM, [dx > 0.5 ? dx - 1 : dx, dy > 0.5 ? dy - 1 : dy, 0]); + this.alignedProjMatrix = alignedM; + + // inverse matrix for conversion from screen coordinates to location + m = mat4.invert(new Float64Array(16) as any, this.pixelMatrix); + if (!m) throw new Error('failed to invert matrix'); + this.pixelMatrixInverse = m; + + this._posMatrixCache = {}; + this._alignedPosMatrixCache = {}; + } + + maxPitchScaleFactor() { + // calcMatrices hasn't run yet + if (!this.pixelMatrixInverse) return 1; + + const coord = this.pointCoordinate(new Point(0, 0)); + const p = [coord.x * this.worldSize, coord.y * this.worldSize, 0, 1] as vec4; + const topPoint = vec4.transformMat4(p, p, this.pixelMatrix); + return topPoint[3] / this.cameraToCenterDistance; + } + + /** + * The camera looks at the map from a 3D (lng, lat, altitude) location. Let's use `cameraLocation` + * as the name for the location under the camera and on the surface of the earth (lng, lat, 0). + * `cameraPoint` is the projected position of the `cameraLocation`. + * + * This point is useful to us because only fill-extrusions that are between `cameraPoint` and + * the query point on the surface of the earth can extend and intersect the query. + * + * When the map is not pitched the `cameraPoint` is equivalent to the center of the map because + * the camera is right above the center of the map. + */ + getCameraPoint() { + const pitch = this._pitch; + const yOffset = Math.tan(pitch) * (this.cameraToCenterDistance || 1); + return this.centerPoint.add(new Point(0, yOffset)); + } + + /** + * When the map is pitched, some of the 3D features that intersect a query will not intersect + * the query at the surface of the earth. Instead the feature may be closer and only intersect + * the query because it extrudes into the air. + * @param queryGeometry - For point queries, the line from the query point to the "camera point", + * for other geometries, the envelope of the query geometry and the "camera point" + * @returns a geometry that includes all of the original query as well as all possible ares of the + * screen where the *base* of a visible extrusion could be. + * + */ + getCameraQueryGeometry(queryGeometry: Array): Array { + const c = this.getCameraPoint(); + + if (queryGeometry.length === 1) { + return [queryGeometry[0], c]; + } else { + let minX = c.x; + let minY = c.y; + let maxX = c.x; + let maxY = c.y; + for (const p of queryGeometry) { + minX = Math.min(minX, p.x); + minY = Math.min(minY, p.y); + maxX = Math.max(maxX, p.x); + maxY = Math.max(maxY, p.y); + } + return [ + new Point(minX, minY), + new Point(maxX, minY), + new Point(maxX, maxY), + new Point(minX, maxY), + new Point(minX, minY), + ]; + } + } + /** + * Return the distance to the camera in clip space from a LngLat. + * This can be compared to the value from the depth buffer (terrain.depthAtPoint) + * to determine whether a point is occluded. + * @param lngLat - the point + * @param elevation - the point's elevation + * @returns depth value in clip space (between 0 and 1) + */ + lngLatToCameraDepth(lngLat: LngLat, elevation: number) { + const coord = this.locationCoordinate(lngLat); + const p = [coord.x * this.worldSize, coord.y * this.worldSize, elevation, 1] as vec4; + vec4.transformMat4(p, p, this.projMatrix); + return p[2] / p[3]; + } +} diff --git a/packages/map/src/map/handler/box_zoom.ts b/packages/map/src/map/handler/box_zoom.ts new file mode 100644 index 00000000000..0a627211132 --- /dev/null +++ b/packages/map/src/map/handler/box_zoom.ts @@ -0,0 +1,178 @@ +import { DOM } from '../util/dom'; + +import { Event } from '../util/evented'; +import { TransformProvider } from './transform-provider'; + +import type Point from '@mapbox/point-geometry'; +import type { Handler } from '../handler_manager'; +import type { Map } from '../map'; + +/** + * The `BoxZoomHandler` allows the user to zoom the map to fit within a bounding box. + * The bounding box is defined by clicking and holding `shift` while dragging the cursor. + * + * @group Handlers + */ +export class BoxZoomHandler implements Handler { + _map: Map; + _tr: TransformProvider; + _el: HTMLElement; + _container: HTMLElement; + _enabled: boolean; + _active: boolean; + _startPos: Point; + _lastPos: Point; + _box: HTMLElement; + _clickTolerance: number; + + /** @internal */ + constructor( + map: Map, + options: { + clickTolerance: number; + }, + ) { + this._map = map; + this._tr = new TransformProvider(map); + this._el = map.getCanvasContainer(); + this._container = map.getContainer(); + this._clickTolerance = options.clickTolerance || 1; + } + + /** + * Returns a Boolean indicating whether the "box zoom" interaction is enabled. + * + * @returns `true` if the "box zoom" interaction is enabled. + */ + isEnabled() { + return !!this._enabled; + } + + /** + * Returns a Boolean indicating whether the "box zoom" interaction is active, i.e. currently being used. + * + * @returns `true` if the "box zoom" interaction is active. + */ + isActive() { + return !!this._active; + } + + /** + * Enables the "box zoom" interaction. + * + * @example + * ```ts + * map.boxZoom.enable(); + * ``` + */ + enable() { + if (this.isEnabled()) return; + this._enabled = true; + } + + /** + * Disables the "box zoom" interaction. + * + * @example + * ```ts + * map.boxZoom.disable(); + * ``` + */ + disable() { + if (!this.isEnabled()) return; + this._enabled = false; + } + + mousedown(e: MouseEvent, point: Point) { + if (!this.isEnabled()) return; + if (!(e.shiftKey && e.button === 0)) return; + + DOM.disableDrag(); + this._startPos = this._lastPos = point; + this._active = true; + } + + mousemoveWindow(e: MouseEvent, point: Point) { + if (!this._active) return; + + const pos = point; + + if ( + this._lastPos.equals(pos) || + (!this._box && pos.dist(this._startPos) < this._clickTolerance) + ) { + return; + } + + const p0 = this._startPos; + this._lastPos = pos; + + if (!this._box) { + this._box = DOM.create('div', 'l7-boxzoom', this._container); + this._container.classList.add('l7-crosshair'); + this._fireEvent('boxzoomstart', e); + } + + const minX = Math.min(p0.x, pos.x), + maxX = Math.max(p0.x, pos.x), + minY = Math.min(p0.y, pos.y), + maxY = Math.max(p0.y, pos.y); + + DOM.setTransform(this._box, `translate(${minX}px,${minY}px)`); + + this._box.style.width = `${maxX - minX}px`; + this._box.style.height = `${maxY - minY}px`; + } + + mouseupWindow(e: MouseEvent, point: Point) { + if (!this._active) return; + + if (e.button !== 0) return; + + const p0 = this._startPos, + p1 = point; + + this.reset(); + + DOM.suppressClick(); + + if (p0.x === p1.x && p0.y === p1.y) { + this._fireEvent('boxzoomcancel', e); + } else { + this._map.fire(new Event('boxzoomend', { originalEvent: e })); + return { + cameraAnimation: (map) => + map.fitScreenCoordinates(p0, p1, this._tr.bearing, { linear: true }), + }; + } + } + + keydown(e: KeyboardEvent) { + if (!this._active) return; + + if (e.keyCode === 27) { + this.reset(); + this._fireEvent('boxzoomcancel', e); + } + } + + reset() { + this._active = false; + + this._container.classList.remove('l7-crosshair'); + + if (this._box) { + DOM.remove(this._box); + this._box = null; + } + + DOM.enableDrag(); + + delete this._startPos; + delete this._lastPos; + } + + _fireEvent(type: string, e: any) { + return this._map.fire(new Event(type, { originalEvent: e })); + } +} diff --git a/packages/map/src/map/handler/click_zoom.ts b/packages/map/src/map/handler/click_zoom.ts new file mode 100644 index 00000000000..8502b0746a7 --- /dev/null +++ b/packages/map/src/map/handler/click_zoom.ts @@ -0,0 +1,57 @@ +import type Point from '@mapbox/point-geometry'; +import type { Handler } from '../handler_manager'; +import type { Map } from '../map'; +import { TransformProvider } from './transform-provider'; + +/** + * The `ClickZoomHandler` allows the user to zoom the map at a point by double clicking + * It is used by other handlers + */ +export class ClickZoomHandler implements Handler { + _tr: TransformProvider; + _enabled: boolean; + _active: boolean; + + /** @internal */ + constructor(map: Map) { + this._tr = new TransformProvider(map); + this.reset(); + } + + reset() { + this._active = false; + } + + dblclick(e: MouseEvent, point: Point) { + e.preventDefault(); + return { + cameraAnimation: (map: Map) => { + map.easeTo( + { + duration: 300, + zoom: this._tr.zoom + (e.shiftKey ? -1 : 1), + around: this._tr.unproject(point), + }, + { originalEvent: e }, + ); + }, + }; + } + + enable() { + this._enabled = true; + } + + disable() { + this._enabled = false; + this.reset(); + } + + isEnabled() { + return this._enabled; + } + + isActive() { + return this._active; + } +} diff --git a/packages/map/src/map/handler/cooperative_gestures.ts b/packages/map/src/map/handler/cooperative_gestures.ts new file mode 100644 index 00000000000..d867e629297 --- /dev/null +++ b/packages/map/src/map/handler/cooperative_gestures.ts @@ -0,0 +1,107 @@ +import type { Handler } from '../handler_manager'; +import { DOM } from '../util/dom'; + +import type { Map } from '../map'; + +/** + * The {@link CooperativeGesturesHandler} options object for the gesture settings + */ +export type GestureOptions = boolean; + +/** + * A `CooperativeGestureHandler` is a control that adds cooperative gesture info when user tries to zoom in/out. + * + * @group Handlers + * + * @example + * ```ts + * const map = new Map({ + * cooperativeGestures: true + * }); + * ``` + * @see [Example: cooperative gestures](https://maplibre.org/maplibre-gl-js-docs/example/cooperative-gestures/) + **/ +export class CooperativeGesturesHandler implements Handler { + _options: GestureOptions; + _map: Map; + _container: HTMLElement; + /** + * This is the key that will allow to bypass the cooperative gesture protection + */ + _bypassKey: 'metaKey' | 'ctrlKey' = + navigator.userAgent.indexOf('Mac') !== -1 ? 'metaKey' : 'ctrlKey'; + _enabled: boolean; + + constructor(map: Map, options: GestureOptions) { + this._map = map; + this._options = options; + this._enabled = false; + } + isActive(): boolean { + return false; + } + reset(): void {} + + _setupUI() { + if (this._container) return; + const mapCanvasContainer = this._map.getCanvasContainer(); + // Add a cooperative gestures class (enable touch-action: pan-x pan-y;) + mapCanvasContainer.classList.add('l7-cooperative-gestures'); + this._container = DOM.create('div', 'l7-cooperative-gesture-screen', mapCanvasContainer); + // Create and append the desktop message div + const desktopDiv = document.createElement('div'); + desktopDiv.className = 'l7-desktop-message'; + desktopDiv.textContent = 'Missing UI string'; + this._container.appendChild(desktopDiv); + // Create and append the mobile message div + const mobileDiv = document.createElement('div'); + mobileDiv.className = 'l7-mobile-message'; + mobileDiv.textContent = 'Missing UI string'; + this._container.appendChild(mobileDiv); + // Remove cooperative gesture screen from the accessibility tree since screenreaders cannot interact with the map using gestures + this._container.setAttribute('aria-hidden', 'true'); + } + + _destoryUI() { + if (this._container) { + DOM.remove(this._container); + const mapCanvasContainer = this._map.getCanvasContainer(); + mapCanvasContainer.classList.remove('l7-cooperative-gestures'); + } + delete this._container; + } + + enable() { + this._setupUI(); + this._enabled = true; + } + + disable() { + this._enabled = false; + this._destoryUI(); + } + + isEnabled() { + return this._enabled; + } + + touchmove(e: TouchEvent) { + this._onCooperativeGesture(e.touches.length === 1); + } + + wheel(e: WheelEvent) { + if (!this._map.scrollZoom.isEnabled()) { + return; + } + this._onCooperativeGesture(!e[this._bypassKey]); + } + + _onCooperativeGesture(showNotification: boolean) { + if (!this._enabled || !showNotification) return; + // Alert user how to scroll/pan + this._container.classList.add('l7-show'); + setTimeout(() => { + this._container.classList.remove('l7-show'); + }, 100); + } +} diff --git a/packages/map/src/map/handler/drag_handler.ts b/packages/map/src/map/handler/drag_handler.ts new file mode 100644 index 00000000000..79a2ff16ebd --- /dev/null +++ b/packages/map/src/map/handler/drag_handler.ts @@ -0,0 +1,176 @@ +import type Point from '@mapbox/point-geometry'; +import type { Handler } from '../handler_manager'; +import { DOM } from '../util/dom'; +import type { DragMoveStateManager } from './drag_move_state_manager'; + +interface DragMovementResult { + bearingDelta?: number; + pitchDelta?: number; + around?: Point; + panDelta?: Point; +} + +export interface DragPanResult extends DragMovementResult { + around: Point; + panDelta: Point; +} + +export interface DragRotateResult extends DragMovementResult { + bearingDelta: number; +} + +export interface DragPitchResult extends DragMovementResult { + pitchDelta: number; +} + +type DragMoveFunction = (lastPoint: Point, point: Point) => T; + +export interface DragMoveHandler extends Handler { + dragStart: (e: E, point: Point) => void; + dragMove: (e: E, point: Point) => T | void; + dragEnd: (e: E) => void; + getClickTolerance: () => number; +} + +export type DragMoveHandlerOptions = { + /** + * If the movement is shorter than this value, consider it a click. + */ + clickTolerance: number; + /** + * The move function to run on a valid movement. + */ + move: DragMoveFunction; + /** + * A class used to manage the state of the drag event - start, checking valid moves, end. See the class documentation for more details. + */ + moveStateManager: DragMoveStateManager; + /** + * A method used to assign the dragStart, dragMove, and dragEnd methods to the relevant event handlers, as well as assigning the contextmenu handler + * @param handler - the handler + */ + assignEvents: (handler: DragMoveHandler) => void; + /** + * Should the move start on the "start" event, or should it start on the first valid move. + */ + activateOnStart?: boolean; + /** + * If true, handler will be enabled during construction + */ + enable?: boolean; +}; + +/** + * A generic class to create handlers for drag events, from both mouse and touch events. + */ +export class DragHandler + implements DragMoveHandler +{ + // Event handlers that may be assigned by the implementations of this class + contextmenu?: Handler['contextmenu']; + mousedown?: Handler['mousedown']; + mousemoveWindow?: Handler['mousemoveWindow']; + mouseup?: Handler['mouseup']; + touchstart?: Handler['touchstart']; + touchmoveWindow?: Handler['touchmoveWindow']; + touchend?: Handler['touchend']; + + _clickTolerance: number; + _moveFunction: DragMoveFunction; + _activateOnStart: boolean; + _active: boolean; + _enabled: boolean; + _moved: boolean; + _lastPoint: Point | null; + _moveStateManager: DragMoveStateManager; + + constructor(options: DragMoveHandlerOptions) { + this._enabled = !!options.enable; + this._moveStateManager = options.moveStateManager; + this._clickTolerance = options.clickTolerance || 1; + this._moveFunction = options.move; + this._activateOnStart = !!options.activateOnStart; + + options.assignEvents(this); + + this.reset(); + } + + reset(e?: E) { + this._active = false; + this._moved = false; + delete this._lastPoint; + this._moveStateManager.endMove(e); + } + + _move(...params: Parameters>) { + const move = this._moveFunction(...params); + if (move.bearingDelta || move.pitchDelta || move.around || move.panDelta) { + this._active = true; + return move; + } + } + + dragStart(e: E, point: Point); + dragStart(e: E, point: Point[]); + dragStart(e: E, point: Point | Point[]) { + if (!this.isEnabled() || this._lastPoint) return; + + if (!this._moveStateManager.isValidStartEvent(e)) return; + this._moveStateManager.startMove(e); + + this._lastPoint = point['length'] ? point[0] : point; + + if (this._activateOnStart && this._lastPoint) this._active = true; + } + + dragMove(e: E, point: Point); + dragMove(e: E, point: Point[]); + dragMove(e: E, point: Point | Point[]) { + if (!this.isEnabled()) return; + const lastPoint = this._lastPoint; + if (!lastPoint) return; + e.preventDefault(); + + if (!this._moveStateManager.isValidMoveEvent(e)) { + this.reset(e); + return; + } + + const movePoint = point['length'] ? point[0] : point; + + if (!this._moved && movePoint.dist(lastPoint) < this._clickTolerance) return; + this._moved = true; + this._lastPoint = movePoint; + + return this._move(lastPoint, movePoint); + } + + dragEnd(e: E) { + if (!this.isEnabled() || !this._lastPoint) return; + if (!this._moveStateManager.isValidEndEvent(e)) return; + if (this._moved) DOM.suppressClick(); + this.reset(e); + } + + enable() { + this._enabled = true; + } + + disable() { + this._enabled = false; + this.reset(); + } + + isEnabled() { + return this._enabled; + } + + isActive() { + return this._active; + } + + getClickTolerance() { + return this._clickTolerance; + } +} diff --git a/packages/map/src/map/handler/drag_move_state_manager.ts b/packages/map/src/map/handler/drag_move_state_manager.ts new file mode 100644 index 00000000000..c098aeb806c --- /dev/null +++ b/packages/map/src/map/handler/drag_move_state_manager.ts @@ -0,0 +1,115 @@ +import { DOM } from '../util/dom'; + +const LEFT_BUTTON = 0; +const RIGHT_BUTTON = 2; + +// the values for each button in MouseEvent.buttons +const BUTTONS_FLAGS = { + [LEFT_BUTTON]: 1, + [RIGHT_BUTTON]: 2, +}; + +function buttonNoLongerPressed(e: MouseEvent, button: number) { + const flag = BUTTONS_FLAGS[button]; + return e.buttons === undefined || (e.buttons & flag) !== flag; +} + +/* + * Drag events are initiated by specific interaction which needs to be tracked until it ends. + * This requires some state management: + * 1. registering the initiating event, + * 2. tracking that it was not canceled / not confusing it with another event firing. + * 3. recognizing the ending event and cleaning up any internal state + * + * Concretely, we implement two state managers: + * 1. MouseMoveStateManager + * Receives a functions that is used to recognize mouse events that should be registered as the + * relevant drag interactions - i.e. dragging with the right mouse button, or while CTRL is pressed. + * 2. OneFingerTouchMoveStateManager + * Checks if a drag event is using one finger, and continuously tracking that this is the same event + * (i.e. to make sure not additional finger has started interacting with the screen before raising + * the first finger). + */ +export interface DragMoveStateManager { + startMove: (e: E) => void; + endMove: (e?: E) => void; + isValidStartEvent: (e: E) => boolean; + isValidMoveEvent: (e: E) => boolean; + isValidEndEvent: (e?: E) => boolean; +} + +export class MouseMoveStateManager implements DragMoveStateManager { + _eventButton: number | undefined; + _correctEvent: (e: MouseEvent) => boolean; + + constructor(options: { checkCorrectEvent: (e: MouseEvent) => boolean }) { + this._correctEvent = options.checkCorrectEvent; + } + + startMove(e: MouseEvent) { + const eventButton = DOM.mouseButton(e); + this._eventButton = eventButton; + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + endMove(_e?: MouseEvent) { + delete this._eventButton; + } + + isValidStartEvent(e: MouseEvent) { + return this._correctEvent(e); + } + + isValidMoveEvent(e: MouseEvent) { + // Some browsers don't fire a `mouseup` when the mouseup occurs outside + // the window or iframe: + // https://github.com/mapbox/mapbox-gl-js/issues/4622 + // + // If the button is no longer pressed during this `mousemove` it may have + // been released outside of the window or iframe. + return !buttonNoLongerPressed(e, this._eventButton); + } + + isValidEndEvent(e: MouseEvent) { + const eventButton = DOM.mouseButton(e); + return eventButton === this._eventButton; + } +} + +export class OneFingerTouchMoveStateManager implements DragMoveStateManager { + _firstTouch: number | undefined; + + constructor() { + this._firstTouch = undefined; + } + + _isOneFingerTouch(e: TouchEvent) { + return e.targetTouches.length === 1; + } + + _isSameTouchEvent(e: TouchEvent) { + return e.targetTouches[0].identifier === this._firstTouch; + } + + startMove(e: TouchEvent) { + const firstTouch = e.targetTouches[0].identifier; + this._firstTouch = firstTouch; + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + endMove(_e?: TouchEvent) { + delete this._firstTouch; + } + + isValidStartEvent(e: TouchEvent) { + return this._isOneFingerTouch(e); + } + + isValidMoveEvent(e: TouchEvent) { + return this._isOneFingerTouch(e) && this._isSameTouchEvent(e); + } + + isValidEndEvent(e: TouchEvent) { + return this._isOneFingerTouch(e) && this._isSameTouchEvent(e); + } +} diff --git a/packages/map/src/map/handler/handler_util.ts b/packages/map/src/map/handler/handler_util.ts new file mode 100644 index 00000000000..a653968e673 --- /dev/null +++ b/packages/map/src/map/handler/handler_util.ts @@ -0,0 +1,13 @@ +import type Point from '@mapbox/point-geometry'; + +export function indexTouches(touches: Array, points: Array) { + if (touches.length !== points.length) + throw new Error( + `The number of touches and points are not equal - touches ${touches.length}, points ${points.length}`, + ); + const obj = {}; + for (let i = 0; i < touches.length; i++) { + obj[touches[i].identifier] = points[i]; + } + return obj; +} diff --git a/packages/map/src/map/handler/keyboard.ts b/packages/map/src/map/handler/keyboard.ts new file mode 100644 index 00000000000..06afe16eaf4 --- /dev/null +++ b/packages/map/src/map/handler/keyboard.ts @@ -0,0 +1,215 @@ +import type { Handler } from '../handler_manager'; +import type { Map } from '../map'; +import { TransformProvider } from './transform-provider'; + +const defaultOptions = { + panStep: 100, + bearingStep: 15, + pitchStep: 10, +}; + +/** + * The `KeyboardHandler` allows the user to zoom, rotate, and pan the map using + * the following keyboard shortcuts: + * + * - `=` / `+`: Increase the zoom level by 1. + * - `Shift-=` / `Shift-+`: Increase the zoom level by 2. + * - `-`: Decrease the zoom level by 1. + * - `Shift--`: Decrease the zoom level by 2. + * - Arrow keys: Pan by 100 pixels. + * - `Shift+⇢`: Increase the rotation by 15 degrees. + * - `Shift+⇠`: Decrease the rotation by 15 degrees. + * - `Shift+⇡`: Increase the pitch by 10 degrees. + * - `Shift+⇣`: Decrease the pitch by 10 degrees. + * + * @group Handlers + */ +export class KeyboardHandler implements Handler { + _tr: TransformProvider; + _enabled: boolean; + _active: boolean; + _panStep: number; + _bearingStep: number; + _pitchStep: number; + _rotationDisabled: boolean; + + /** @internal */ + constructor(map: Map) { + this._tr = new TransformProvider(map); + const stepOptions = defaultOptions; + this._panStep = stepOptions.panStep; + this._bearingStep = stepOptions.bearingStep; + this._pitchStep = stepOptions.pitchStep; + this._rotationDisabled = false; + } + + reset() { + this._active = false; + } + + keydown(e: KeyboardEvent) { + if (e.altKey || e.ctrlKey || e.metaKey) return; + + let zoomDir = 0; + let bearingDir = 0; + let pitchDir = 0; + let xDir = 0; + let yDir = 0; + + switch (e.keyCode) { + case 61: + case 107: + case 171: + case 187: + zoomDir = 1; + break; + + case 189: + case 109: + case 173: + zoomDir = -1; + break; + + case 37: + if (e.shiftKey) { + bearingDir = -1; + } else { + e.preventDefault(); + xDir = -1; + } + break; + + case 39: + if (e.shiftKey) { + bearingDir = 1; + } else { + e.preventDefault(); + xDir = 1; + } + break; + + case 38: + if (e.shiftKey) { + pitchDir = 1; + } else { + e.preventDefault(); + yDir = -1; + } + break; + + case 40: + if (e.shiftKey) { + pitchDir = -1; + } else { + e.preventDefault(); + yDir = 1; + } + break; + + default: + return; + } + + if (this._rotationDisabled) { + bearingDir = 0; + pitchDir = 0; + } + + return { + cameraAnimation: (map: Map) => { + const tr = this._tr; + map.easeTo( + { + duration: 300, + easeId: 'keyboardHandler', + easing: easeOut, + + zoom: zoomDir ? Math.round(tr.zoom) + zoomDir * (e.shiftKey ? 2 : 1) : tr.zoom, + bearing: tr.bearing + bearingDir * this._bearingStep, + pitch: tr.pitch + pitchDir * this._pitchStep, + offset: [-xDir * this._panStep, -yDir * this._panStep], + center: tr.center, + }, + { originalEvent: e }, + ); + }, + }; + } + + /** + * Enables the "keyboard rotate and zoom" interaction. + * + * @example + * ```ts + * map.keyboard.enable(); + * ``` + */ + enable() { + this._enabled = true; + } + + /** + * Disables the "keyboard rotate and zoom" interaction. + * + * @example + * ```ts + * map.keyboard.disable(); + * ``` + */ + disable() { + this._enabled = false; + this.reset(); + } + + /** + * Returns a Boolean indicating whether the "keyboard rotate and zoom" + * interaction is enabled. + * + * @returns `true` if the "keyboard rotate and zoom" + * interaction is enabled. + */ + isEnabled() { + return this._enabled; + } + + /** + * Returns true if the handler is enabled and has detected the start of a + * zoom/rotate gesture. + * + * @returns `true` if the handler is enabled and has detected the + * start of a zoom/rotate gesture. + */ + isActive() { + return this._active; + } + + /** + * Disables the "keyboard pan/rotate" interaction, leaving the + * "keyboard zoom" interaction enabled. + * + * @example + * ```ts + * map.keyboard.disableRotation(); + * ``` + */ + disableRotation() { + this._rotationDisabled = true; + } + + /** + * Enables the "keyboard pan/rotate" interaction. + * + * @example + * ```ts + * map.keyboard.enable(); + * map.keyboard.enableRotation(); + * ``` + */ + enableRotation() { + this._rotationDisabled = false; + } +} + +function easeOut(t: number) { + return t * (2 - t); +} diff --git a/packages/map/src/map/handler/map_event.ts b/packages/map/src/map/handler/map_event.ts new file mode 100644 index 00000000000..65ca90c787e --- /dev/null +++ b/packages/map/src/map/handler/map_event.ts @@ -0,0 +1,163 @@ +import type Point from '@mapbox/point-geometry'; +import { MapMouseEvent, MapTouchEvent, MapWheelEvent } from '../events'; +import type { Handler } from '../handler_manager'; +import type { Map } from '../map'; + +export class MapEventHandler implements Handler { + _mousedownPos: Point; + _clickTolerance: number; + _map: Map; + + constructor( + map: Map, + options: { + clickTolerance: number; + }, + ) { + this._map = map; + this._clickTolerance = options.clickTolerance; + } + + reset() { + delete this._mousedownPos; + } + + wheel(e: WheelEvent) { + // If mapEvent.preventDefault() is called by the user, prevent handlers such as: + // - ScrollZoom + return this._firePreventable(new MapWheelEvent(e.type, this._map, e)); + } + + mousedown(e: MouseEvent, point: Point) { + this._mousedownPos = point; + // If mapEvent.preventDefault() is called by the user, prevent handlers such as: + // - MousePan + // - MouseRotate + // - MousePitch + // - DblclickHandler + return this._firePreventable(new MapMouseEvent(e.type, this._map, e)); + } + + mouseup(e: MouseEvent) { + this._map.fire(new MapMouseEvent(e.type, this._map, e)); + } + + click(e: MouseEvent, point: Point) { + if (this._mousedownPos && this._mousedownPos.dist(point) >= this._clickTolerance) return; + this._map.fire(new MapMouseEvent(e.type, this._map, e)); + } + + dblclick(e: MouseEvent) { + // If mapEvent.preventDefault() is called by the user, prevent handlers such as: + // - DblClickZoom + return this._firePreventable(new MapMouseEvent(e.type, this._map, e)); + } + + mouseover(e: MouseEvent) { + this._map.fire(new MapMouseEvent(e.type, this._map, e)); + } + + mouseout(e: MouseEvent) { + this._map.fire(new MapMouseEvent(e.type, this._map, e)); + } + + touchstart(e: TouchEvent) { + // If mapEvent.preventDefault() is called by the user, prevent handlers such as: + // - TouchPan + // - TouchZoom + // - TouchRotate + // - TouchPitch + // - TapZoom + // - SwipeZoom + return this._firePreventable(new MapTouchEvent(e.type, this._map, e)); + } + + touchmove(e: TouchEvent) { + this._map.fire(new MapTouchEvent(e.type, this._map, e)); + } + + touchend(e: TouchEvent) { + this._map.fire(new MapTouchEvent(e.type, this._map, e)); + } + + touchcancel(e: TouchEvent) { + this._map.fire(new MapTouchEvent(e.type, this._map, e)); + } + + _firePreventable(mapEvent: MapMouseEvent | MapTouchEvent | MapWheelEvent) { + this._map.fire(mapEvent); + if (mapEvent.defaultPrevented) { + // returning an object marks the handler as active and resets other handlers + return {}; + } + } + + isEnabled() { + return true; + } + + isActive() { + return false; + } + enable() {} + disable() {} +} + +export class BlockableMapEventHandler { + _map: Map; + _delayContextMenu: boolean; + _ignoreContextMenu: boolean; + _contextMenuEvent: MouseEvent; + + constructor(map: Map) { + this._map = map; + } + + reset() { + this._delayContextMenu = false; + this._ignoreContextMenu = true; + delete this._contextMenuEvent; + } + + mousemove(e: MouseEvent) { + // mousemove map events should not be fired when interaction handlers (pan, rotate, etc) are active + this._map.fire(new MapMouseEvent(e.type, this._map, e)); + } + + mousedown() { + this._delayContextMenu = true; + this._ignoreContextMenu = false; + } + + mouseup() { + this._delayContextMenu = false; + if (this._contextMenuEvent) { + this._map.fire(new MapMouseEvent('contextmenu', this._map, this._contextMenuEvent)); + delete this._contextMenuEvent; + } + } + contextmenu(e: MouseEvent) { + if (this._delayContextMenu) { + // Mac: contextmenu fired on mousedown; we save it until mouseup for consistency's sake + this._contextMenuEvent = e; + } else if (!this._ignoreContextMenu) { + // Windows: contextmenu fired on mouseup, so fire event now + this._map.fire(new MapMouseEvent(e.type, this._map, e)); + } + + // prevent browser context menu when necessary + if (this._map.listens('contextmenu')) { + e.preventDefault(); + } + } + + isEnabled() { + return true; + } + + isActive() { + return false; + } + enable() {} + disable() {} +} diff --git a/packages/map/src/map/handler/mouse.ts b/packages/map/src/map/handler/mouse.ts new file mode 100644 index 00000000000..31bbf8d3657 --- /dev/null +++ b/packages/map/src/map/handler/mouse.ts @@ -0,0 +1,108 @@ +import type Point from '@mapbox/point-geometry'; + +import { DOM } from '../util/dom'; +import type { + DragMoveHandler, + DragPanResult, + DragPitchResult, + DragRotateResult, +} from './drag_handler'; +import { DragHandler } from './drag_handler'; +import { MouseMoveStateManager } from './drag_move_state_manager'; + +/** + * `MousePanHandler` allows the user to pan the map by clicking and dragging + */ +export interface MousePanHandler extends DragMoveHandler {} +/** + * `MouseRotateHandler` allows the user to rotate the map by clicking and dragging + */ +export interface MouseRotateHandler extends DragMoveHandler {} +/** + * `MousePitchHandler` allows the user to zoom the map by pitching + */ +export interface MousePitchHandler extends DragMoveHandler {} + +const LEFT_BUTTON = 0; +const RIGHT_BUTTON = 2; + +const assignEvents = (handler: DragHandler) => { + handler.mousedown = handler.dragStart; + handler.mousemoveWindow = handler.dragMove; + handler.mouseup = handler.dragEnd; + handler.contextmenu = (e: MouseEvent) => { + e.preventDefault(); + }; +}; + +export const generateMousePanHandler = ({ + enable, + clickTolerance, +}: { + clickTolerance: number; + enable?: boolean; +}): MousePanHandler => { + const mouseMoveStateManager = new MouseMoveStateManager({ + checkCorrectEvent: (e: MouseEvent) => DOM.mouseButton(e) === LEFT_BUTTON && !e.ctrlKey, + }); + return new DragHandler({ + clickTolerance, + move: (lastPoint: Point, point: Point) => ({ around: point, panDelta: point.sub(lastPoint) }), + activateOnStart: true, + moveStateManager: mouseMoveStateManager, + enable, + assignEvents, + }); +}; + +export const generateMouseRotationHandler = ({ + enable, + clickTolerance, + bearingDegreesPerPixelMoved = 0.8, +}: { + clickTolerance: number; + bearingDegreesPerPixelMoved?: number; + enable?: boolean; +}): MouseRotateHandler => { + const mouseMoveStateManager = new MouseMoveStateManager({ + checkCorrectEvent: (e: MouseEvent): boolean => + (DOM.mouseButton(e) === LEFT_BUTTON && e.ctrlKey) || DOM.mouseButton(e) === RIGHT_BUTTON, + }); + return new DragHandler({ + clickTolerance, + move: (lastPoint: Point, point: Point) => ({ + bearingDelta: (point.x - lastPoint.x) * bearingDegreesPerPixelMoved, + }), + // prevent browser context menu when necessary; we don't allow it with rotation + // because we can't discern rotation gesture start from contextmenu on Mac + moveStateManager: mouseMoveStateManager, + enable, + assignEvents, + }); +}; + +export const generateMousePitchHandler = ({ + enable, + clickTolerance, + pitchDegreesPerPixelMoved = -0.5, +}: { + clickTolerance: number; + pitchDegreesPerPixelMoved?: number; + enable?: boolean; +}): MousePitchHandler => { + const mouseMoveStateManager = new MouseMoveStateManager({ + checkCorrectEvent: (e: MouseEvent): boolean => + (DOM.mouseButton(e) === LEFT_BUTTON && e.ctrlKey) || DOM.mouseButton(e) === RIGHT_BUTTON, + }); + return new DragHandler({ + clickTolerance, + move: (lastPoint: Point, point: Point) => ({ + pitchDelta: (point.y - lastPoint.y) * pitchDegreesPerPixelMoved, + }), + // prevent browser context menu when necessary; we don't allow it with rotation + // because we can't discern rotation gesture start from contextmenu on Mac + moveStateManager: mouseMoveStateManager, + enable, + assignEvents, + }); +}; diff --git a/packages/map/src/map/handler/one_finger_touch_drag.ts b/packages/map/src/map/handler/one_finger_touch_drag.ts new file mode 100644 index 00000000000..1d085c455a3 --- /dev/null +++ b/packages/map/src/map/handler/one_finger_touch_drag.ts @@ -0,0 +1,57 @@ +import type Point from '@mapbox/point-geometry'; + +import type { DragMoveHandler, DragPitchResult, DragRotateResult } from './drag_handler'; +import { DragHandler } from './drag_handler'; +import { OneFingerTouchMoveStateManager } from './drag_move_state_manager'; + +export interface OneFingerTouchRotateHandler + extends DragMoveHandler {} +export interface OneFingerTouchPitchHandler extends DragMoveHandler {} + +const assignEvents = (handler: DragHandler) => { + handler.touchstart = handler.dragStart; + handler.touchmoveWindow = handler.dragMove; + handler.touchend = handler.dragEnd; +}; + +export const generateOneFingerTouchRotationHandler = ({ + enable, + clickTolerance, + bearingDegreesPerPixelMoved = 0.8, +}: { + clickTolerance: number; + bearingDegreesPerPixelMoved?: number; + enable?: boolean; +}): OneFingerTouchRotateHandler => { + const touchMoveStateManager = new OneFingerTouchMoveStateManager(); + return new DragHandler({ + clickTolerance, + move: (lastPoint: Point, point: Point) => ({ + bearingDelta: (point.x - lastPoint.x) * bearingDegreesPerPixelMoved, + }), + moveStateManager: touchMoveStateManager, + enable, + assignEvents, + }); +}; + +export const generateOneFingerTouchPitchHandler = ({ + enable, + clickTolerance, + pitchDegreesPerPixelMoved = -0.5, +}: { + clickTolerance: number; + pitchDegreesPerPixelMoved?: number; + enable?: boolean; +}): OneFingerTouchPitchHandler => { + const touchMoveStateManager = new OneFingerTouchMoveStateManager(); + return new DragHandler({ + clickTolerance, + move: (lastPoint: Point, point: Point) => ({ + pitchDelta: (point.y - lastPoint.y) * pitchDegreesPerPixelMoved, + }), + moveStateManager: touchMoveStateManager, + enable, + assignEvents, + }); +}; diff --git a/packages/map/src/map/handler/scroll_zoom.ts b/packages/map/src/map/handler/scroll_zoom.ts new file mode 100644 index 00000000000..4d612e1df25 --- /dev/null +++ b/packages/map/src/map/handler/scroll_zoom.ts @@ -0,0 +1,363 @@ +import { DOM } from '../util/dom'; + +import { LngLat } from '../geo/lng_lat'; +import { browser } from '../util/browser'; +import { bezier, defaultEasing, interpolates } from '../util/util'; +import { TransformProvider } from './transform-provider'; + +import type Point from '@mapbox/point-geometry'; +import type { Handler } from '../handler_manager'; +import type { Map } from '../map'; +import type { AroundCenterOptions } from './two_fingers_touch'; + +// deltaY value for mouse scroll wheel identification +const wheelZoomDelta = 4.000244140625; + +// These magic numbers control the rate of zoom. Trackpad events fire at a greater +// frequency than mouse scroll wheel, so reduce the zoom rate per wheel tick +const defaultZoomRate = 1 / 100; +const wheelZoomRate = 1 / 450; + +// upper bound on how much we scale the map in any single render frame; this +// is used to limit zoom rate in the case of very fast scrolling +const maxScalePerFrame = 2; + +/** + * The `ScrollZoomHandler` allows the user to zoom the map by scrolling. + * + * @group Handlers + */ +export class ScrollZoomHandler implements Handler { + _map: Map; + _tr: TransformProvider; + _enabled: boolean; + _active: boolean; + _zooming: boolean; + _aroundCenter: boolean; + _around: LngLat; + _aroundPoint: Point; + _type: 'wheel' | 'trackpad' | null; + _lastValue: number; + _timeout: ReturnType; // used for delayed-handling of a single wheel movement + _finishTimeout: ReturnType; // used to delay final '{move,zoom}end' events + + _lastWheelEvent: any; + _lastWheelEventTime: number; + + _startZoom: number; + _targetZoom: number; + _delta: number; + _easing: (a: number) => number; + _prevEase: { + start: number; + duration: number; + easing: (_: number) => number; + }; + + _frameId: boolean; + _triggerRenderFrame: () => void; + + _defaultZoomRate: number; + _wheelZoomRate: number; + + /** @internal */ + constructor(map: Map, triggerRenderFrame: () => void) { + this._map = map; + this._tr = new TransformProvider(map); + this._triggerRenderFrame = triggerRenderFrame; + + this._delta = 0; + + this._defaultZoomRate = defaultZoomRate; + this._wheelZoomRate = wheelZoomRate; + } + + /** + * Set the zoom rate of a trackpad + * @param zoomRate - 1/100 The rate used to scale trackpad movement to a zoom value. + * @example + * Speed up trackpad zoom + * ```ts + * map.scrollZoom.setZoomRate(1/25); + * ``` + */ + setZoomRate(zoomRate: number) { + this._defaultZoomRate = zoomRate; + } + + /** + * Set the zoom rate of a mouse wheel + * @param wheelZoomRate - 1/450 The rate used to scale mouse wheel movement to a zoom value. + * @example + * Slow down zoom of mouse wheel + * ```ts + * map.scrollZoom.setWheelZoomRate(1/600); + * ``` + */ + setWheelZoomRate(wheelZoomRate: number) { + this._wheelZoomRate = wheelZoomRate; + } + + /** + * Returns a Boolean indicating whether the "scroll to zoom" interaction is enabled. + * @returns `true` if the "scroll to zoom" interaction is enabled. + */ + isEnabled() { + return !!this._enabled; + } + + /* + * Active state is turned on and off with every scroll wheel event and is set back to false before the map + * render is called, so _active is not a good candidate for determining if a scroll zoom animation is in + * progress. + */ + isActive() { + return !!this._active || this._finishTimeout !== undefined; + } + + isZooming() { + return !!this._zooming; + } + + /** + * Enables the "scroll to zoom" interaction. + * + * @param options - Options object. + * @example + * ```ts + * map.scrollZoom.enable(); + * map.scrollZoom.enable({ around: 'center' }) + * ``` + */ + enable(options?: AroundCenterOptions | boolean) { + if (this.isEnabled()) return; + this._enabled = true; + this._aroundCenter = !!options && (options as AroundCenterOptions).around === 'center'; + } + + /** + * Disables the "scroll to zoom" interaction. + * + * @example + * ```ts + * map.scrollZoom.disable(); + * ``` + */ + disable() { + if (!this.isEnabled()) return; + this._enabled = false; + } + + wheel(e: WheelEvent) { + if (!this.isEnabled()) return; + if (this._map.cooperativeGestures.isEnabled() && !e[this._map.cooperativeGestures._bypassKey]) { + return; + } + let value = e.deltaMode === WheelEvent.DOM_DELTA_LINE ? e.deltaY * 40 : e.deltaY; + const now = browser.now(), + timeDelta = now - (this._lastWheelEventTime || 0); + + this._lastWheelEventTime = now; + + if (value !== 0 && value % wheelZoomDelta === 0) { + // This one is definitely a mouse wheel event. + this._type = 'wheel'; + } else if (value !== 0 && Math.abs(value) < 4) { + // This one is definitely a trackpad event because it is so small. + this._type = 'trackpad'; + } else if (timeDelta > 400) { + // This is likely a new scroll action. + this._type = null; + this._lastValue = value; + + // Start a timeout in case this was a singular event, and dely it by up to 40ms. + this._timeout = setTimeout(this._onTimeout, 40, e); + } else if (!this._type) { + // This is a repeating event, but we don't know the type of event just yet. + // If the delta per time is small, we assume it's a fast trackpad; otherwise we switch into wheel mode. + this._type = Math.abs(timeDelta * value) < 200 ? 'trackpad' : 'wheel'; + + // Make sure our delayed event isn't fired again, because we accumulate + // the previous event (which was less than 40ms ago) into this event. + if (this._timeout) { + clearTimeout(this._timeout); + this._timeout = null; + value += this._lastValue; + } + } + + // Slow down zoom if shift key is held for more precise zooming + if (e.shiftKey && value) value = value / 4; + + // Only fire the callback if we actually know what type of scrolling device the user uses. + if (this._type) { + this._lastWheelEvent = e; + this._delta -= value; + if (!this._active) { + this._start(e); + } + } + + e.preventDefault(); + } + + _onTimeout = (initialEvent: MouseEvent) => { + this._type = 'wheel'; + this._delta -= this._lastValue; + if (!this._active) { + this._start(initialEvent); + } + }; + + _start(e: MouseEvent) { + if (!this._delta) return; + + if (this._frameId) { + this._frameId = null; + } + + this._active = true; + if (!this.isZooming()) { + this._zooming = true; + } + + if (this._finishTimeout) { + clearTimeout(this._finishTimeout); + delete this._finishTimeout; + } + + const pos = DOM.mousePos(this._map.getCanvasContainer(), e); + const tr = this._tr; + + if (pos.y > tr.transform.height / 2 - tr.transform.getHorizon()) { + this._around = LngLat.convert(this._aroundCenter ? tr.center : tr.unproject(pos)); + } else { + // Do not use current cursor position if above the horizon to avoid 'unproject' this point + // as it is not mapped into 'coords' framebuffer or inversible with 'pixelMatrixInverse'. + this._around = LngLat.convert(tr.center); + } + + this._aroundPoint = tr.transform.locationPoint(this._around); + if (!this._frameId) { + this._frameId = true; + this._triggerRenderFrame(); + } + } + + renderFrame() { + if (!this._frameId) return; + this._frameId = null; + + if (!this.isActive()) return; + const tr = this._tr.transform; + + // if we've had scroll events since the last render frame, consume the + // accumulated delta, and update the target zoom level accordingly + if (this._delta !== 0) { + // For trackpad events and single mouse wheel ticks, use the default zoom rate + const zoomRate = + this._type === 'wheel' && Math.abs(this._delta) > wheelZoomDelta + ? this._wheelZoomRate + : this._defaultZoomRate; + // Scale by sigmoid of scroll wheel delta. + let scale = maxScalePerFrame / (1 + Math.exp(-Math.abs(this._delta * zoomRate))); + + if (this._delta < 0 && scale !== 0) { + scale = 1 / scale; + } + + const fromScale = + typeof this._targetZoom === 'number' ? tr.zoomScale(this._targetZoom) : tr.scale; + this._targetZoom = Math.min( + tr.maxZoom, + Math.max(tr.minZoom, tr.scaleZoom(fromScale * scale)), + ); + + // if this is a mouse wheel, refresh the starting zoom and easing + // function we're using to smooth out the zooming between wheel + // events + if (this._type === 'wheel') { + this._startZoom = tr.zoom; + this._easing = this._smoothOutEasing(200); + } + + this._delta = 0; + } + + const targetZoom = typeof this._targetZoom === 'number' ? this._targetZoom : tr.zoom; + const startZoom = this._startZoom; + const easing = this._easing; + + let finished = false; + let zoom; + if (this._type === 'wheel' && startZoom && easing) { + const t = Math.min((browser.now() - this._lastWheelEventTime) / 200, 1); + const k = easing(t); + zoom = interpolates.number(startZoom, targetZoom, k); + if (t < 1) { + if (!this._frameId) { + this._frameId = true; + } + } else { + finished = true; + } + } else { + zoom = targetZoom; + finished = true; + } + + this._active = true; + + if (finished) { + this._active = false; + this._finishTimeout = setTimeout(() => { + this._zooming = false; + this._triggerRenderFrame(); + delete this._targetZoom; + delete this._finishTimeout; + }, 200); + } + + return { + noInertia: true, + needsRenderFrame: !finished, + zoomDelta: zoom - tr.zoom, + around: this._aroundPoint, + originalEvent: this._lastWheelEvent, + }; + } + + _smoothOutEasing(duration: number) { + let easing = defaultEasing; + + if (this._prevEase) { + const currentEase = this._prevEase; + const t = (browser.now() - currentEase.start) / currentEase.duration; + const speed = currentEase.easing(t + 0.01) - currentEase.easing(t); + + // Quick hack to make new bezier that is continuous with last + const x = (0.27 / Math.sqrt(speed * speed + 0.0001)) * 0.01; + const y = Math.sqrt(0.27 * 0.27 - x * x); + + easing = bezier(x, y, 0.25, 1); + } + + this._prevEase = { + start: browser.now(), + duration, + easing, + }; + + return easing; + } + + reset() { + this._active = false; + this._zooming = false; + delete this._targetZoom; + if (this._finishTimeout) { + clearTimeout(this._finishTimeout); + delete this._finishTimeout; + } + } +} diff --git a/packages/map/src/map/handler/shim/dblclick_zoom.ts b/packages/map/src/map/handler/shim/dblclick_zoom.ts new file mode 100644 index 00000000000..ee977c7b812 --- /dev/null +++ b/packages/map/src/map/handler/shim/dblclick_zoom.ts @@ -0,0 +1,63 @@ +import type { ClickZoomHandler } from '../click_zoom'; +import type { TapZoomHandler } from '../tap_zoom'; + +/** + * The `DoubleClickZoomHandler` allows the user to zoom the map at a point by + * double clicking or double tapping. + * + * @group Handlers + */ +export class DoubleClickZoomHandler { + _clickZoom: ClickZoomHandler; + _tapZoom: TapZoomHandler; + + /** @internal */ + constructor(clickZoom: ClickZoomHandler, TapZoom: TapZoomHandler) { + this._clickZoom = clickZoom; + this._tapZoom = TapZoom; + } + + /** + * Enables the "double click to zoom" interaction. + * + * @example + * ```ts + * map.doubleClickZoom.enable(); + * ``` + */ + enable() { + this._clickZoom.enable(); + this._tapZoom.enable(); + } + + /** + * Disables the "double click to zoom" interaction. + * + * @example + * ```ts + * map.doubleClickZoom.disable(); + * ``` + */ + disable() { + this._clickZoom.disable(); + this._tapZoom.disable(); + } + + /** + * Returns a Boolean indicating whether the "double click to zoom" interaction is enabled. + * + * @returns `true` if the "double click to zoom" interaction is enabled. + */ + isEnabled() { + return this._clickZoom.isEnabled() && this._tapZoom.isEnabled(); + } + + /** + * Returns a Boolean indicating whether the "double click to zoom" interaction is active, i.e. currently being used. + * + * @returns `true` if the "double click to zoom" interaction is active. + */ + isActive() { + return this._clickZoom.isActive() || this._tapZoom.isActive(); + } +} diff --git a/packages/map/src/map/handler/shim/drag_pan.ts b/packages/map/src/map/handler/shim/drag_pan.ts new file mode 100644 index 00000000000..271fd4129e1 --- /dev/null +++ b/packages/map/src/map/handler/shim/drag_pan.ts @@ -0,0 +1,103 @@ +import type { MousePanHandler } from '../mouse'; +import type { TouchPanHandler } from '../touch_pan'; + +/** + * A {@link DragPanHandler} options object + */ +export type DragPanOptions = { + /** + * factor used to scale the drag velocity + * @defaultValue 0 + */ + linearity?: number; + /** + * easing function applied to `map.panTo` when applying the drag. + * @param t - the easing function + * @defaultValue bezier(0, 0, 0.3, 1) + */ + easing?: (t: number) => number; + /** + * the maximum value of the drag velocity. + * @defaultValue 1400 + */ + deceleration?: number; + /** + * the rate at which the speed reduces after the pan ends. + * @defaultValue 2500 + */ + maxSpeed?: number; +}; + +/** + * The `DragPanHandler` allows the user to pan the map by clicking and dragging + * the cursor. + * + * @group Handlers + */ +export class DragPanHandler { + _el: HTMLElement; + _mousePan: MousePanHandler; + _touchPan: TouchPanHandler; + _inertiaOptions: DragPanOptions | boolean; + + /** @internal */ + constructor(el: HTMLElement, mousePan: MousePanHandler, touchPan: TouchPanHandler) { + this._el = el; + this._mousePan = mousePan; + this._touchPan = touchPan; + } + + /** + * Enables the "drag to pan" interaction. + * + * @param options - Options object + * @example + * ```ts + * map.dragPan.enable(); + * map.dragPan.enable({ + * linearity: 0.3, + * easing: bezier(0, 0, 0.3, 1), + * maxSpeed: 1400, + * deceleration: 2500, + * }); + * ``` + */ + enable(options?: DragPanOptions | boolean) { + this._inertiaOptions = options || {}; + this._mousePan.enable(); + this._touchPan.enable(); + this._el.classList.add('l7-touch-drag-pan'); + } + + /** + * Disables the "drag to pan" interaction. + * + * @example + * ```ts + * map.dragPan.disable(); + * ``` + */ + disable() { + this._mousePan.disable(); + this._touchPan.disable(); + this._el.classList.remove('l7-touch-drag-pan'); + } + + /** + * Returns a Boolean indicating whether the "drag to pan" interaction is enabled. + * + * @returns `true` if the "drag to pan" interaction is enabled. + */ + isEnabled() { + return this._mousePan.isEnabled() && this._touchPan.isEnabled(); + } + + /** + * Returns a Boolean indicating whether the "drag to pan" interaction is active, i.e. currently being used. + * + * @returns `true` if the "drag to pan" interaction is active. + */ + isActive() { + return this._mousePan.isActive() || this._touchPan.isActive(); + } +} diff --git a/packages/map/src/map/handler/shim/drag_rotate.ts b/packages/map/src/map/handler/shim/drag_rotate.ts new file mode 100644 index 00000000000..c5a022197fb --- /dev/null +++ b/packages/map/src/map/handler/shim/drag_rotate.ts @@ -0,0 +1,81 @@ +import type { MousePitchHandler, MouseRotateHandler } from '../mouse'; + +/** + * Options object for `DragRotateHandler`. + */ +export type DragRotateHandlerOptions = { + /** + * Control the map pitch in addition to the bearing + * @defaultValue true + */ + pitchWithRotate: boolean; +}; + +/** + * The `DragRotateHandler` allows the user to rotate the map by clicking and + * dragging the cursor while holding the right mouse button or `ctrl` key. + * + * @group Handlers + */ +export class DragRotateHandler { + _mouseRotate: MouseRotateHandler; + _mousePitch: MousePitchHandler; + _pitchWithRotate: boolean; + + /** @internal */ + constructor( + options: DragRotateHandlerOptions, + mouseRotate: MouseRotateHandler, + mousePitch: MousePitchHandler, + ) { + this._pitchWithRotate = options.pitchWithRotate; + this._mouseRotate = mouseRotate; + this._mousePitch = mousePitch; + } + + /** + * Enables the "drag to rotate" interaction. + * + * @example + * ```ts + * map.dragRotate.enable(); + * ``` + */ + enable() { + this._mouseRotate.enable(); + if (this._pitchWithRotate) this._mousePitch.enable(); + } + + /** + * Disables the "drag to rotate" interaction. + * + * @example + * ```ts + * map.dragRotate.disable(); + * ``` + */ + disable() { + this._mouseRotate.disable(); + this._mousePitch.disable(); + } + + /** + * Returns a Boolean indicating whether the "drag to rotate" interaction is enabled. + * + * @returns `true` if the "drag to rotate" interaction is enabled. + */ + isEnabled() { + return ( + this._mouseRotate.isEnabled() && (!this._pitchWithRotate || this._mousePitch.isEnabled()) + ); + } + + /** + * Returns a Boolean indicating whether the "drag to rotate" interaction is active, i.e. currently being used. + * + * @returns `true` if the "drag to rotate" interaction is active. + */ + isActive() { + return this._mouseRotate.isActive() || this._mousePitch.isActive(); + } +} diff --git a/packages/map/src/map/handler/shim/two_fingers_touch.ts b/packages/map/src/map/handler/shim/two_fingers_touch.ts new file mode 100644 index 00000000000..023be4f14b9 --- /dev/null +++ b/packages/map/src/map/handler/shim/two_fingers_touch.ts @@ -0,0 +1,124 @@ +import type { TapDragZoomHandler } from '../tap_drag_zoom'; +import type { + AroundCenterOptions, + TwoFingersTouchRotateHandler, + TwoFingersTouchZoomHandler, +} from '../two_fingers_touch'; + +/** + * The `TwoFingersTouchZoomRotateHandler` allows the user to zoom and rotate the map by + * pinching on a touchscreen. + * + * They can zoom with one finger by double tapping and dragging. On the second tap, + * hold the finger down and drag up or down to zoom in or out. + * + * @group Handlers + */ +export class TwoFingersTouchZoomRotateHandler { + _el: HTMLElement; + _touchZoom: TwoFingersTouchZoomHandler; + _touchRotate: TwoFingersTouchRotateHandler; + _tapDragZoom: TapDragZoomHandler; + _rotationDisabled: boolean; + _enabled: boolean; + + /** @internal */ + constructor( + el: HTMLElement, + touchZoom: TwoFingersTouchZoomHandler, + touchRotate: TwoFingersTouchRotateHandler, + tapDragZoom: TapDragZoomHandler, + ) { + this._el = el; + this._touchZoom = touchZoom; + this._touchRotate = touchRotate; + this._tapDragZoom = tapDragZoom; + this._rotationDisabled = false; + this._enabled = true; + } + + /** + * Enables the "pinch to rotate and zoom" interaction. + * + * @param options - Options object. + * + * @example + * ```ts + * map.touchZoomRotate.enable(); + * map.touchZoomRotate.enable({ around: 'center' }); + * ``` + */ + enable(options?: AroundCenterOptions | boolean | null) { + this._touchZoom.enable(options); + if (!this._rotationDisabled) this._touchRotate.enable(options); + this._tapDragZoom.enable(); + this._el.classList.add('l7-touch-zoom-rotate'); + } + + /** + * Disables the "pinch to rotate and zoom" interaction. + * + * @example + * ```ts + * map.touchZoomRotate.disable(); + * ``` + */ + disable() { + this._touchZoom.disable(); + this._touchRotate.disable(); + this._tapDragZoom.disable(); + this._el.classList.remove('l7-touch-zoom-rotate'); + } + + /** + * Returns a Boolean indicating whether the "pinch to rotate and zoom" interaction is enabled. + * + * @returns `true` if the "pinch to rotate and zoom" interaction is enabled. + */ + isEnabled() { + return ( + this._touchZoom.isEnabled() && + (this._rotationDisabled || this._touchRotate.isEnabled()) && + this._tapDragZoom.isEnabled() + ); + } + + /** + * Returns true if the handler is enabled and has detected the start of a zoom/rotate gesture. + * + * @returns `true` if the handler is active, `false` otherwise + */ + isActive() { + return ( + this._touchZoom.isActive() || this._touchRotate.isActive() || this._tapDragZoom.isActive() + ); + } + + /** + * Disables the "pinch to rotate" interaction, leaving the "pinch to zoom" + * interaction enabled. + * + * @example + * ```ts + * map.touchZoomRotate.disableRotation(); + * ``` + */ + disableRotation() { + this._rotationDisabled = true; + this._touchRotate.disable(); + } + + /** + * Enables the "pinch to rotate" interaction. + * + * @example + * ```ts + * map.touchZoomRotate.enable(); + * map.touchZoomRotate.enableRotation(); + * ``` + */ + enableRotation() { + this._rotationDisabled = false; + if (this._touchZoom.isEnabled()) this._touchRotate.enable(); + } +} diff --git a/packages/map/src/map/handler/tap_drag_zoom.ts b/packages/map/src/map/handler/tap_drag_zoom.ts new file mode 100644 index 00000000000..20c2350830b --- /dev/null +++ b/packages/map/src/map/handler/tap_drag_zoom.ts @@ -0,0 +1,110 @@ +import type Point from '@mapbox/point-geometry'; +import type { Handler } from '../handler_manager'; +import { MAX_DIST, MAX_TAP_INTERVAL, TapRecognizer } from './tap_recognizer'; + +/** + * A `TapDragZoomHandler` allows the user to zoom the map at a point by double tapping. It also allows the user pan the map by dragging. + */ +export class TapDragZoomHandler implements Handler { + _enabled: boolean; + _active: boolean; + _swipePoint: Point; + _swipeTouch: number; + _tapTime: number; + _tapPoint: Point; + _tap: TapRecognizer; + + constructor() { + this._tap = new TapRecognizer({ + numTouches: 1, + numTaps: 1, + }); + + this.reset(); + } + + reset() { + this._active = false; + delete this._swipePoint; + delete this._swipeTouch; + delete this._tapTime; + delete this._tapPoint; + this._tap.reset(); + } + + touchstart(e: TouchEvent, points: Array, mapTouches: Array) { + if (this._swipePoint) return; + + if (!this._tapTime) { + this._tap.touchstart(e, points, mapTouches); + } else { + const swipePoint = points[0]; + + const soonEnough = e.timeStamp - this._tapTime < MAX_TAP_INTERVAL; + const closeEnough = this._tapPoint.dist(swipePoint) < MAX_DIST; + + if (!soonEnough || !closeEnough) { + this.reset(); + } else if (mapTouches.length > 0) { + this._swipePoint = swipePoint; + this._swipeTouch = mapTouches[0].identifier; + } + } + } + + touchmove(e: TouchEvent, points: Array, mapTouches: Array) { + if (!this._tapTime) { + this._tap.touchmove(e, points, mapTouches); + } else if (this._swipePoint) { + if (mapTouches[0].identifier !== this._swipeTouch) { + return; + } + + const newSwipePoint = points[0]; + const dist = newSwipePoint.y - this._swipePoint.y; + this._swipePoint = newSwipePoint; + + e.preventDefault(); + this._active = true; + + return { + zoomDelta: dist / 128, + }; + } + } + + touchend(e: TouchEvent, points: Array, mapTouches: Array) { + if (!this._tapTime) { + const point = this._tap.touchend(e, points, mapTouches); + if (point) { + this._tapTime = e.timeStamp; + this._tapPoint = point; + } + } else if (this._swipePoint) { + if (mapTouches.length === 0) { + this.reset(); + } + } + } + + touchcancel() { + this.reset(); + } + + enable() { + this._enabled = true; + } + + disable() { + this._enabled = false; + this.reset(); + } + + isEnabled() { + return this._enabled; + } + + isActive() { + return this._active; + } +} diff --git a/packages/map/src/map/handler/tap_recognizer.ts b/packages/map/src/map/handler/tap_recognizer.ts new file mode 100644 index 00000000000..4caa08b6cd9 --- /dev/null +++ b/packages/map/src/map/handler/tap_recognizer.ts @@ -0,0 +1,129 @@ +import Point from '@mapbox/point-geometry'; +import { indexTouches } from './handler_util'; + +function getCentroid(points: Array) { + const sum = new Point(0, 0); + for (const point of points) { + sum._add(point); + } + return sum.div(points.length); +} + +export const MAX_TAP_INTERVAL = 500; +const MAX_TOUCH_TIME = 500; +export const MAX_DIST = 30; + +export class SingleTapRecognizer { + numTouches: number; + centroid: Point; + startTime: number; + aborted: boolean; + touches: { + [k in number | string]: Point; + }; + + constructor(options: { numTouches: number }) { + this.reset(); + this.numTouches = options.numTouches; + } + + reset() { + delete this.centroid; + delete this.startTime; + delete this.touches; + this.aborted = false; + } + + touchstart(e: TouchEvent, points: Array, mapTouches: Array) { + if (this.centroid || mapTouches.length > this.numTouches) { + this.aborted = true; + } + if (this.aborted) { + return; + } + + if (this.startTime === undefined) { + this.startTime = e.timeStamp; + } + + if (mapTouches.length === this.numTouches) { + this.centroid = getCentroid(points); + this.touches = indexTouches(mapTouches, points); + } + } + + touchmove(e: TouchEvent, points: Array, mapTouches: Array) { + if (this.aborted || !this.centroid) return; + + const newTouches = indexTouches(mapTouches, points); + for (const id in this.touches) { + const prevPos = this.touches[id]; + const pos = newTouches[id]; + if (!pos || pos.dist(prevPos) > MAX_DIST) { + this.aborted = true; + } + } + } + + touchend(e: TouchEvent, points: Array, mapTouches: Array) { + if (!this.centroid || e.timeStamp - this.startTime > MAX_TOUCH_TIME) { + this.aborted = true; + } + + if (mapTouches.length === 0) { + const centroid = !this.aborted && this.centroid; + this.reset(); + if (centroid) return centroid; + } + } +} + +export class TapRecognizer { + singleTap: SingleTapRecognizer; + numTaps: number; + lastTime: number; + lastTap: Point; + count: number; + + constructor(options: { numTaps: number; numTouches: number }) { + this.singleTap = new SingleTapRecognizer(options); + this.numTaps = options.numTaps; + this.reset(); + } + + reset() { + this.lastTime = Infinity; + delete this.lastTap; + this.count = 0; + this.singleTap.reset(); + } + + touchstart(e: TouchEvent, points: Array, mapTouches: Array) { + this.singleTap.touchstart(e, points, mapTouches); + } + + touchmove(e: TouchEvent, points: Array, mapTouches: Array) { + this.singleTap.touchmove(e, points, mapTouches); + } + + touchend(e: TouchEvent, points: Array, mapTouches: Array) { + const tap = this.singleTap.touchend(e, points, mapTouches); + if (tap) { + const soonEnough = e.timeStamp - this.lastTime < MAX_TAP_INTERVAL; + const closeEnough = !this.lastTap || this.lastTap.dist(tap) < MAX_DIST; + + if (!soonEnough || !closeEnough) { + this.reset(); + } + + this.count++; + this.lastTime = e.timeStamp; + this.lastTap = tap; + + if (this.count === this.numTaps) { + this.reset(); + return tap; + } + } + } +} diff --git a/packages/map/src/map/handler/tap_zoom.ts b/packages/map/src/map/handler/tap_zoom.ts new file mode 100644 index 00000000000..ecbfbe43240 --- /dev/null +++ b/packages/map/src/map/handler/tap_zoom.ts @@ -0,0 +1,106 @@ +import type Point from '@mapbox/point-geometry'; +import type { Handler } from '../handler_manager'; +import type { Map } from '../map'; +import { TapRecognizer } from './tap_recognizer'; +import { TransformProvider } from './transform-provider'; + +/** + * A `TapZoomHandler` allows the user to zoom the map at a point by double tapping + */ +export class TapZoomHandler implements Handler { + _tr: TransformProvider; + _enabled: boolean; + _active: boolean; + _zoomIn: TapRecognizer; + _zoomOut: TapRecognizer; + + constructor(map: Map) { + this._tr = new TransformProvider(map); + this._zoomIn = new TapRecognizer({ + numTouches: 1, + numTaps: 2, + }); + + this._zoomOut = new TapRecognizer({ + numTouches: 2, + numTaps: 1, + }); + + this.reset(); + } + + reset() { + this._active = false; + this._zoomIn.reset(); + this._zoomOut.reset(); + } + + touchstart(e: TouchEvent, points: Array, mapTouches: Array) { + this._zoomIn.touchstart(e, points, mapTouches); + this._zoomOut.touchstart(e, points, mapTouches); + } + + touchmove(e: TouchEvent, points: Array, mapTouches: Array) { + this._zoomIn.touchmove(e, points, mapTouches); + this._zoomOut.touchmove(e, points, mapTouches); + } + + touchend(e: TouchEvent, points: Array, mapTouches: Array) { + const zoomInPoint = this._zoomIn.touchend(e, points, mapTouches); + const zoomOutPoint = this._zoomOut.touchend(e, points, mapTouches); + const tr = this._tr; + + if (zoomInPoint) { + this._active = true; + e.preventDefault(); + setTimeout(() => this.reset(), 0); + return { + cameraAnimation: (map: Map) => + map.easeTo( + { + duration: 300, + zoom: tr.zoom + 1, + around: tr.unproject(zoomInPoint), + }, + { originalEvent: e }, + ), + }; + } else if (zoomOutPoint) { + this._active = true; + e.preventDefault(); + setTimeout(() => this.reset(), 0); + return { + cameraAnimation: (map: Map) => + map.easeTo( + { + duration: 300, + zoom: tr.zoom - 1, + around: tr.unproject(zoomOutPoint), + }, + { originalEvent: e }, + ), + }; + } + } + + touchcancel() { + this.reset(); + } + + enable() { + this._enabled = true; + } + + disable() { + this._enabled = false; + this.reset(); + } + + isEnabled() { + return this._enabled; + } + + isActive() { + return this._active; + } +} diff --git a/packages/map/src/map/handler/touch_pan.ts b/packages/map/src/map/handler/touch_pan.ts new file mode 100644 index 00000000000..adc4c15b591 --- /dev/null +++ b/packages/map/src/map/handler/touch_pan.ts @@ -0,0 +1,109 @@ +import Point from '@mapbox/point-geometry'; +import type { Handler } from '../handler_manager'; +import type { Map } from '../map'; +import { indexTouches } from './handler_util'; + +/** + * A `TouchPanHandler` allows the user to pan the map using touch gestures. + */ +export class TouchPanHandler implements Handler { + _enabled: boolean; + _active: boolean; + _touches: { + [k in string | number]: Point; + }; + _clickTolerance: number; + _sum: Point; + _map: Map; + + constructor(options: { clickTolerance: number }, map: Map) { + this._clickTolerance = options.clickTolerance || 1; + this._map = map; + this.reset(); + } + + reset() { + this._active = false; + this._touches = {}; + this._sum = new Point(0, 0); + } + + minTouchs() { + return this._map.cooperativeGestures.isEnabled() ? 2 : 1; + } + + touchstart(e: TouchEvent, points: Array, mapTouches: Array) { + return this._calculateTransform(e, points, mapTouches); + } + + touchmove(e: TouchEvent, points: Array, mapTouches: Array) { + if (!this._active || mapTouches.length < this.minTouchs()) return; + e.preventDefault(); + return this._calculateTransform(e, points, mapTouches); + } + + touchend(e: TouchEvent, points: Array, mapTouches: Array) { + this._calculateTransform(e, points, mapTouches); + + if (this._active && mapTouches.length < this.minTouchs()) { + this.reset(); + } + } + + touchcancel() { + this.reset(); + } + + _calculateTransform(e: TouchEvent, points: Array, mapTouches: Array) { + if (mapTouches.length > 0) this._active = true; + + const touches = indexTouches(mapTouches, points); + + const touchPointSum = new Point(0, 0); + const touchDeltaSum = new Point(0, 0); + let touchDeltaCount = 0; + + for (const identifier in touches) { + const point = touches[identifier]; + const prevPoint = this._touches[identifier]; + if (prevPoint) { + touchPointSum._add(point); + touchDeltaSum._add(point.sub(prevPoint)); + touchDeltaCount++; + touches[identifier] = point; + } + } + + this._touches = touches; + + if (touchDeltaCount < this.minTouchs() || !touchDeltaSum.mag()) return; + + const panDelta = touchDeltaSum.div(touchDeltaCount); + this._sum._add(panDelta); + if (this._sum.mag() < this._clickTolerance) return; + + const around = touchPointSum.div(touchDeltaCount); + + return { + around, + panDelta, + }; + } + + enable() { + this._enabled = true; + } + + disable() { + this._enabled = false; + this.reset(); + } + + isEnabled() { + return this._enabled; + } + + isActive() { + return this._active; + } +} diff --git a/packages/map/src/map/handler/transform-provider.ts b/packages/map/src/map/handler/transform-provider.ts new file mode 100644 index 00000000000..b6a3b6240e7 --- /dev/null +++ b/packages/map/src/map/handler/transform-provider.ts @@ -0,0 +1,43 @@ +import Point from '@mapbox/point-geometry'; +import type { PointLike } from '../camera'; +import type { LngLat } from '../geo/lng_lat'; +import type { Transform } from '../geo/transform'; +import type { Map } from '../map'; + +/** + * @internal + * Shared utilities for the Handler classes to access the correct camera state. + * If Camera.transformCameraUpdate is specified, the "desired state" of camera may differ from the state used for rendering. + * The handlers need the "desired state" to track accumulated changes. + */ +export class TransformProvider { + _map: Map; + + constructor(map: Map) { + this._map = map; + } + + get transform(): Transform { + return this._map._requestedCameraState || this._map.transform; + } + + get center() { + return { lng: this.transform.center.lng, lat: this.transform.center.lat }; + } + + get zoom() { + return this.transform.zoom; + } + + get pitch() { + return this.transform.pitch; + } + + get bearing() { + return this.transform.bearing; + } + + unproject(point: PointLike): LngLat { + return this.transform.pointLocation(Point.convert(point)); + } +} diff --git a/packages/map/src/map/handler/two_fingers_touch.ts b/packages/map/src/map/handler/two_fingers_touch.ts new file mode 100644 index 00000000000..96b1c1c0eb3 --- /dev/null +++ b/packages/map/src/map/handler/two_fingers_touch.ts @@ -0,0 +1,342 @@ +import type Point from '@mapbox/point-geometry'; +import type { Handler, HandlerResult } from '../handler_manager'; +import type { Map } from '../map'; +import { DOM } from '../util/dom'; + +/** + * An options object sent to the enable function of some of the handlers + */ +export type AroundCenterOptions = { + /** + * If "center" is passed, map will zoom around the center of map + */ + around: 'center'; +}; + +/** + * The `TwoFingersTouchHandler`s allows the user to zoom, pitch and rotate the map using two fingers + * + */ +abstract class TwoFingersTouchHandler implements Handler { + _enabled?: boolean; + _active?: boolean; + _firstTwoTouches?: [number, number]; + _vector?: Point; + _startVector?: Point; + _aroundCenter?: boolean; + + /** @internal */ + constructor() { + this.reset(); + } + + reset(): void { + this._active = false; + delete this._firstTwoTouches; + } + + abstract _start(points: [Point, Point]): void; + abstract _move( + points: [Point, Point], + pinchAround: Point | null, + e: TouchEvent, + ): HandlerResult | void; + + touchstart(e: TouchEvent, points: Array, mapTouches: Array): void { + //log('touchstart', points, e.target.innerHTML, e.targetTouches.length ? e.targetTouches[0].target.innerHTML: undefined); + if (this._firstTwoTouches || mapTouches.length < 2) return; + + this._firstTwoTouches = [mapTouches[0].identifier, mapTouches[1].identifier]; + + // implemented by child classes + this._start([points[0], points[1]]); + } + + touchmove(e: TouchEvent, points: Array, mapTouches: Array): HandlerResult | void { + if (!this._firstTwoTouches) return; + + e.preventDefault(); + + const [idA, idB] = this._firstTwoTouches; + const a = getTouchById(mapTouches, points, idA); + const b = getTouchById(mapTouches, points, idB); + if (!a || !b) return; + const pinchAround = this._aroundCenter ? null : a.add(b).div(2); + + // implemented by child classes + return this._move([a, b], pinchAround, e); + } + + touchend(e: TouchEvent, points: Array, mapTouches: Array): void { + if (!this._firstTwoTouches) return; + + const [idA, idB] = this._firstTwoTouches; + const a = getTouchById(mapTouches, points, idA); + const b = getTouchById(mapTouches, points, idB); + if (a && b) return; + + if (this._active) DOM.suppressClick(); + + this.reset(); + } + + touchcancel(): void { + this.reset(); + } + + /** + * Enables the "drag to pitch" interaction. + * + * @example + * ```ts + * map.touchPitch.enable(); + * ``` + */ + enable(options?: AroundCenterOptions | boolean | null): void { + this._enabled = true; + this._aroundCenter = !!options && (options as AroundCenterOptions).around === 'center'; + } + + /** + * Disables the "drag to pitch" interaction. + * + * @example + * ```ts + * map.touchPitch.disable(); + * ``` + */ + disable(): void { + this._enabled = false; + this.reset(); + } + + /** + * Returns a Boolean indicating whether the "drag to pitch" interaction is enabled. + * + * @returns `true` if the "drag to pitch" interaction is enabled. + */ + isEnabled(): boolean { + return !!this._enabled; + } + + /** + * Returns a Boolean indicating whether the "drag to pitch" interaction is active, i.e. currently being used. + * + * @returns `true` if the "drag to pitch" interaction is active. + */ + isActive(): boolean { + return !!this._active; + } +} + +function getTouchById( + mapTouches: Array, + points: Array, + identifier: number, +): Point | undefined { + for (let i = 0; i < mapTouches.length; i++) { + if (mapTouches[i].identifier === identifier) return points[i]; + } + return undefined; +} + +/* ZOOM */ + +const ZOOM_THRESHOLD = 0.1; + +function getZoomDelta(distance: number, lastDistance: number): number { + return Math.log(distance / lastDistance) / Math.LN2; +} + +/** + * The `TwoFingersTouchHandler`s allows the user to zoom the map two fingers + * + * @group Handlers + */ +export class TwoFingersTouchZoomHandler extends TwoFingersTouchHandler { + _distance?: number; + _startDistance?: number; + + reset() { + super.reset(); + delete this._distance; + delete this._startDistance; + } + + _start(points: [Point, Point]): void { + this._startDistance = this._distance = points[0].dist(points[1]); + } + + _move(points: [Point, Point], pinchAround: Point | null): HandlerResult | void { + const lastDistance = this._distance!; + this._distance = points[0].dist(points[1]); + if ( + !this._active && + Math.abs(getZoomDelta(this._distance, this._startDistance!)) < ZOOM_THRESHOLD + ) + return; + this._active = true; + return { + zoomDelta: getZoomDelta(this._distance, lastDistance), + pinchAround, + }; + } +} + +/* ROTATE */ + +const ROTATION_THRESHOLD = 25; // pixels along circumference of touch circle + +function getBearingDelta(a: Point, b: Point): number { + return (a.angleWith(b) * 180) / Math.PI; +} + +/** + * The `TwoFingersTouchHandler`s allows the user to rotate the map two fingers + * + * @group Handlers + */ +export class TwoFingersTouchRotateHandler extends TwoFingersTouchHandler { + _minDiameter?: number; + + reset(): void { + super.reset(); + delete this._minDiameter; + delete this._startVector; + delete this._vector; + } + + _start(points: [Point, Point]): void { + this._startVector = this._vector = points[0].sub(points[1]); + this._minDiameter = points[0].dist(points[1]); + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _move(points: [Point, Point], pinchAround: Point | null, _e: TouchEvent): HandlerResult | void { + const lastVector = this._vector!; + this._vector = points[0].sub(points[1]); + + if (!this._active && this._isBelowThreshold(this._vector)) return; + this._active = true; + + return { + bearingDelta: getBearingDelta(this._vector, lastVector), + pinchAround, + }; + } + + _isBelowThreshold(vector: Point): boolean { + /* + * The threshold before a rotation actually happens is configured in + * pixels along the circumference of the circle formed by the two fingers. + * This makes the threshold in degrees larger when the fingers are close + * together and smaller when the fingers are far apart. + * + * Use the smallest diameter from the whole gesture to reduce sensitivity + * when pinching in and out. + */ + + this._minDiameter = Math.min(this._minDiameter!, vector.mag()); + const circumference = Math.PI * this._minDiameter; + const threshold = (ROTATION_THRESHOLD / circumference) * 360; + + const bearingDeltaSinceStart = getBearingDelta(vector, this._startVector!); + return Math.abs(bearingDeltaSinceStart) < threshold; + } +} + +/* PITCH */ + +function isVertical(vector: Point): boolean { + return Math.abs(vector.y) > Math.abs(vector.x); +} + +const ALLOWED_SINGLE_TOUCH_TIME = 100; + +/** + * The `TwoFingersTouchPitchHandler` allows the user to pitch the map by dragging up and down with two fingers. + * + * @group Handlers + */ +export class TwoFingersTouchPitchHandler extends TwoFingersTouchHandler { + _valid?: boolean; + _firstMove?: number; + _lastPoints?: [Point, Point]; + _map: Map; + _currentTouchCount: number = 0; + + constructor(map: Map) { + super(); + this._map = map; + } + + reset(): void { + super.reset(); + this._valid = undefined; + delete this._firstMove; + delete this._lastPoints; + } + + touchstart(e: TouchEvent, points: Array, mapTouches: Array): void { + super.touchstart(e, points, mapTouches); + this._currentTouchCount = mapTouches.length; + } + + _start(points: [Point, Point]): void { + this._lastPoints = points; + if (isVertical(points[0].sub(points[1]))) { + // fingers are more horizontal than vertical + this._valid = false; + } + } + + _move(points: [Point, Point], center: Point | null, e: TouchEvent): HandlerResult | void { + // If cooperative gestures is enabled, we need a 3-finger minimum for this gesture to register + if (this._map.cooperativeGestures.isEnabled() && this._currentTouchCount < 3) { + return; + } + + const vectorA = points[0].sub(this._lastPoints![0]); + const vectorB = points[1].sub(this._lastPoints![1]); + + this._valid = this.gestureBeginsVertically(vectorA, vectorB, e.timeStamp); + if (!this._valid) return; + + this._lastPoints = points; + this._active = true; + const yDeltaAverage = (vectorA.y + vectorB.y) / 2; + const degreesPerPixelMoved = -0.5; + return { + pitchDelta: yDeltaAverage * degreesPerPixelMoved, + }; + } + + gestureBeginsVertically(vectorA: Point, vectorB: Point, timeStamp: number): boolean | undefined { + if (this._valid !== undefined) return this._valid; + + const threshold = 2; + const movedA = vectorA.mag() >= threshold; + const movedB = vectorB.mag() >= threshold; + + // neither finger has moved a meaningful amount, wait + if (!movedA && !movedB) return; + + // One finger has moved and the other has not. + // If enough time has passed, decide it is not a pitch. + if (!movedA || !movedB) { + if (this._firstMove === undefined) { + this._firstMove = timeStamp; + } + + if (timeStamp - this._firstMove < ALLOWED_SINGLE_TOUCH_TIME) { + // still waiting for a movement from the second finger + return undefined; + } else { + return false; + } + } + + const isSameDirection = vectorA.y > 0 === vectorB.y > 0; + return isVertical(vectorA) && isVertical(vectorB) && isSameDirection; + } +} diff --git a/packages/map/src/map/handler_inertia.ts b/packages/map/src/map/handler_inertia.ts new file mode 100644 index 00000000000..89cb25fd72d --- /dev/null +++ b/packages/map/src/map/handler_inertia.ts @@ -0,0 +1,168 @@ +import Point from '@mapbox/point-geometry'; +import type { DragPanOptions } from './handler/shim/drag_pan'; +import type { Map } from './map'; +import { browser } from './util/browser'; +import { bezier, clamp, extend } from './util/util'; + +const defaultInertiaOptions = { + linearity: 0.3, + easing: bezier(0, 0, 0.3, 1), +}; + +const defaultPanInertiaOptions = extend( + { + deceleration: 2500, + maxSpeed: 1400, + }, + defaultInertiaOptions, +); + +const defaultZoomInertiaOptions = extend( + { + deceleration: 20, + maxSpeed: 1400, + }, + defaultInertiaOptions, +); + +const defaultBearingInertiaOptions = extend( + { + deceleration: 1000, + maxSpeed: 360, + }, + defaultInertiaOptions, +); + +const defaultPitchInertiaOptions = extend( + { + deceleration: 1000, + maxSpeed: 90, + }, + defaultInertiaOptions, +); + +export type InertiaOptions = { + linearity: number; + easing: (t: number) => number; + deceleration: number; + maxSpeed: number; +}; + +export class HandlerInertia { + _map: Map; + _inertiaBuffer: Array<{ + time: number; + settings: any; + }>; + + constructor(map: Map) { + this._map = map; + this.clear(); + } + + clear() { + this._inertiaBuffer = []; + } + + record(settings: any) { + this._drainInertiaBuffer(); + this._inertiaBuffer.push({ time: browser.now(), settings }); + } + + _drainInertiaBuffer() { + const inertia = this._inertiaBuffer, + now = browser.now(), + cutoff = 160; //msec + + while (inertia.length > 0 && now - inertia[0].time > cutoff) inertia.shift(); + } + + _onMoveEnd(panInertiaOptions?: DragPanOptions | boolean) { + this._drainInertiaBuffer(); + if (this._inertiaBuffer.length < 2) { + return; + } + + const deltas = { + zoom: 0, + bearing: 0, + pitch: 0, + pan: new Point(0, 0), + pinchAround: undefined, + around: undefined, + }; + + for (const { settings } of this._inertiaBuffer) { + deltas.zoom += settings.zoomDelta || 0; + deltas.bearing += settings.bearingDelta || 0; + deltas.pitch += settings.pitchDelta || 0; + if (settings.panDelta) deltas.pan._add(settings.panDelta); + if (settings.around) deltas.around = settings.around; + if (settings.pinchAround) deltas.pinchAround = settings.pinchAround; + } + + const lastEntry = this._inertiaBuffer[this._inertiaBuffer.length - 1]; + const duration = lastEntry.time - this._inertiaBuffer[0].time; + + const easeOptions = {} as any; + + if (deltas.pan.mag()) { + const result = calculateEasing( + deltas.pan.mag(), + duration, + extend({}, defaultPanInertiaOptions, panInertiaOptions || {}), + ); + easeOptions.offset = deltas.pan.mult(result.amount / deltas.pan.mag()); + easeOptions.center = this._map.transform.center; + extendDuration(easeOptions, result); + } + + if (deltas.zoom) { + const result = calculateEasing(deltas.zoom, duration, defaultZoomInertiaOptions); + easeOptions.zoom = this._map.transform.zoom + result.amount; + extendDuration(easeOptions, result); + } + + if (deltas.bearing) { + const result = calculateEasing(deltas.bearing, duration, defaultBearingInertiaOptions); + easeOptions.bearing = this._map.transform.bearing + clamp(result.amount, -179, 179); + extendDuration(easeOptions, result); + } + + if (deltas.pitch) { + const result = calculateEasing(deltas.pitch, duration, defaultPitchInertiaOptions); + easeOptions.pitch = this._map.transform.pitch + result.amount; + extendDuration(easeOptions, result); + } + + if (easeOptions.zoom || easeOptions.bearing) { + const last = deltas.pinchAround === undefined ? deltas.around : deltas.pinchAround; + easeOptions.around = last ? this._map.unproject(last) : this._map.getCenter(); + } + + this.clear(); + return extend(easeOptions, { + noMoveStart: true, + }); + } +} + +// Unfortunately zoom, bearing, etc can't have different durations and easings so +// we need to choose one. We use the longest duration and it's corresponding easing. +function extendDuration(easeOptions, result) { + if (!easeOptions.duration || easeOptions.duration < result.duration) { + easeOptions.duration = result.duration; + easeOptions.easing = result.easing; + } +} + +function calculateEasing(amount, inertiaDuration: number, inertiaOptions) { + const { maxSpeed, linearity, deceleration } = inertiaOptions; + const speed = clamp((amount * linearity) / (inertiaDuration / 1000), -maxSpeed, maxSpeed); + const duration = Math.abs(speed) / (deceleration * linearity); + return { + easing: inertiaOptions.easing, + duration: duration * 1000, + amount: speed * (duration / 2), + }; +} diff --git a/packages/map/src/map/handler_manager.ts b/packages/map/src/map/handler_manager.ts new file mode 100644 index 00000000000..bdff7a8a2a9 --- /dev/null +++ b/packages/map/src/map/handler_manager.ts @@ -0,0 +1,690 @@ +import Point from '@mapbox/point-geometry'; +import { BoxZoomHandler } from './handler/box_zoom'; +import { ClickZoomHandler } from './handler/click_zoom'; +import { CooperativeGesturesHandler } from './handler/cooperative_gestures'; +import { KeyboardHandler } from './handler/keyboard'; +import { BlockableMapEventHandler, MapEventHandler } from './handler/map_event'; +import { + generateMousePanHandler, + generateMousePitchHandler, + generateMouseRotationHandler, +} from './handler/mouse'; +import { ScrollZoomHandler } from './handler/scroll_zoom'; +import { DoubleClickZoomHandler } from './handler/shim/dblclick_zoom'; +import { DragPanHandler } from './handler/shim/drag_pan'; +import { DragRotateHandler } from './handler/shim/drag_rotate'; +import { TwoFingersTouchZoomRotateHandler } from './handler/shim/two_fingers_touch'; +import { TapDragZoomHandler } from './handler/tap_drag_zoom'; +import { TapZoomHandler } from './handler/tap_zoom'; +import { TouchPanHandler } from './handler/touch_pan'; +import { + TwoFingersTouchPitchHandler, + TwoFingersTouchRotateHandler, + TwoFingersTouchZoomHandler, +} from './handler/two_fingers_touch'; +import { HandlerInertia } from './handler_inertia'; +import type { CompleteMapOptions, Map } from './map'; +import { browser } from './util/browser'; +import { DOM } from './util/dom'; +import { Event } from './util/evented'; +import { extend } from './util/util'; + +const isMoving = (p: EventsInProgress) => p.zoom || p.drag || p.pitch || p.rotate; + +class RenderFrameEvent extends Event { + public type: string = 'renderFrame'; + public timeStamp: number; + + constructor(type: string, timeStamp: number) { + super(type); + this.timeStamp = timeStamp; + } +} + +/** + * Handlers interpret dom events and return camera changes that should be + * applied to the map (`HandlerResult`s). The camera changes are all deltas. + * The handler itself should have no knowledge of the map's current state. + * This makes it easier to merge multiple results and keeps handlers simpler. + * For example, if there is a mousedown and mousemove, the mousePan handler + * would return a `panDelta` on the mousemove. + */ +export interface Handler { + enable(): void; + disable(): void; + isEnabled(): boolean; + /** + * This is used to indicate if the handler is currently active or not. + * In case a handler is active, it will block other handlers from getting the relevant events. + * There is an allow list of handlers that can be active at the same time, which is configured when adding a handler. + */ + isActive(): boolean; + /** + * `reset` can be called by the manager at any time and must reset everything to it's original state + */ + reset(): void; + // Handlers can optionally implement these methods. + // They are called with dom events whenever those dom evens are received. + readonly touchstart?: ( + e: TouchEvent, + points: Array, + mapTouches: Array, + ) => HandlerResult | void; + readonly touchmove?: ( + e: TouchEvent, + points: Array, + mapTouches: Array, + ) => HandlerResult | void; + readonly touchmoveWindow?: ( + e: TouchEvent, + points: Array, + mapTouches: Array, + ) => HandlerResult | void; + readonly touchend?: ( + e: TouchEvent, + points: Array, + mapTouches: Array, + ) => HandlerResult | void; + readonly touchcancel?: ( + e: TouchEvent, + points: Array, + mapTouches: Array, + ) => HandlerResult | void; + readonly mousedown?: (e: MouseEvent, point: Point) => HandlerResult | void; + readonly mousemove?: (e: MouseEvent, point: Point) => HandlerResult | void; + readonly mousemoveWindow?: (e: MouseEvent, point: Point) => HandlerResult | void; + readonly mouseup?: (e: MouseEvent, point: Point) => HandlerResult | void; + readonly mouseupWindow?: (e: MouseEvent, point: Point) => HandlerResult | void; + readonly dblclick?: (e: MouseEvent, point: Point) => HandlerResult | void; + readonly contextmenu?: (e: MouseEvent) => HandlerResult | void; + readonly wheel?: (e: WheelEvent, point: Point) => HandlerResult | void; + readonly keydown?: (e: KeyboardEvent) => HandlerResult | void; + readonly keyup?: (e: KeyboardEvent) => HandlerResult | void; + /** + * `renderFrame` is the only non-dom event. It is called during render + * frames and can be used to smooth camera changes (see scroll handler). + */ + readonly renderFrame?: () => HandlerResult | void; +} + +/** + * All handler methods that are called with events can optionally return a `HandlerResult`. + */ +export type HandlerResult = { + panDelta?: Point; + zoomDelta?: number; + bearingDelta?: number; + pitchDelta?: number; + /** + * the point to not move when changing the camera + */ + around?: Point | null; + /** + * same as above, except for pinch actions, which are given higher priority + */ + pinchAround?: Point | null; + /** + * A method that can fire a one-off easing by directly changing the map's camera. + */ + cameraAnimation?: (map: Map) => any; + /** + * The last three properties are needed by only one handler: scrollzoom. + * The DOM event to be used as the `originalEvent` on any camera change events. + */ + originalEvent?: Event; + /** + * Makes the manager trigger a frame, allowing the handler to return multiple results over time (see scrollzoom). + */ + needsRenderFrame?: boolean; + /** + * The camera changes won't get recorded for inertial zooming. + */ + noInertia?: boolean; +}; + +export type EventInProgress = { + handlerName: string; + originalEvent: Event; +}; + +export type EventsInProgress = { + zoom?: EventInProgress; + pitch?: EventInProgress; + rotate?: EventInProgress; + drag?: EventInProgress; +}; + +function hasChange(result: HandlerResult) { + return ( + (result.panDelta && result.panDelta.mag()) || + result.zoomDelta || + result.bearingDelta || + result.pitchDelta + ); +} + +export class HandlerManager { + _map: Map; + _el: HTMLElement; + _handlers: Array<{ + handlerName: string; + handler: Handler; + allowed: Array; + }>; + _eventsInProgress: EventsInProgress; + _frameId: number; + _inertia: HandlerInertia; + _bearingSnap: number; + _handlersById: { [x: string]: Handler }; + _updatingCamera: boolean; + _changes: Array<[HandlerResult, EventsInProgress, { [handlerName: string]: Event }]>; + _zoom: { handlerName: string }; + _previousActiveHandlers: { [x: string]: Handler }; + _listeners: Array< + [ + Window | Document | HTMLElement, + string, + ( + | { + passive?: boolean; + capture?: boolean; + } + | undefined + ), + ] + >; + + constructor(map: Map, options: CompleteMapOptions) { + this._map = map; + this._el = this._map.getCanvasContainer(); + this._handlers = []; + this._handlersById = {}; + this._changes = []; + + this._inertia = new HandlerInertia(map); + this._bearingSnap = options.bearingSnap || 7; + this._previousActiveHandlers = {}; + + // Track whether map is currently moving, to compute start/move/end events + this._eventsInProgress = {}; + + this._addDefaultHandlers(options); + + const el = this._el; + + this._listeners = [ + // This needs to be `passive: true` so that a double tap fires two + // pairs of touchstart/end events in iOS Safari 13. If this is set to + // `passive: false` then the second pair of events is only fired if + // preventDefault() is called on the first touchstart. Calling preventDefault() + // undesirably prevents click events. + [el, 'touchstart', { passive: true }], + // This needs to be `passive: false` so that scrolls and pinches can be + // prevented in browsers that don't support `touch-actions: none`, for example iOS Safari 12. + [el, 'touchmove', { passive: false }], + [el, 'touchend', undefined], + [el, 'touchcancel', undefined], + + [el, 'mousedown', undefined], + [el, 'mousemove', undefined], + [el, 'mouseup', undefined], + + // Bind window-level event listeners for move and up/end events. In the absence of + // the pointer capture API, which is not supported by all necessary platforms, + // window-level event listeners give us the best shot at capturing events that + // fall outside the map canvas element. Use `{capture: true}` for the move event + // to prevent map move events from being fired during a drag. + [document, 'mousemove', { capture: true }], + [document, 'mouseup', undefined], + + [el, 'mouseover', undefined], + [el, 'mouseout', undefined], + [el, 'dblclick', undefined], + [el, 'click', undefined], + + [el, 'keydown', { capture: false }], + [el, 'keyup', undefined], + + [el, 'wheel', { passive: false }], + [el, 'contextmenu', undefined], + + [window, 'blur', undefined], + ]; + + for (const [target, type, listenerOptions] of this._listeners) { + DOM.addEventListener( + target, + type, + target === document ? this.handleWindowEvent : this.handleEvent, + listenerOptions, + ); + } + } + + destroy() { + for (const [target, type, listenerOptions] of this._listeners) { + DOM.removeEventListener( + target, + type, + target === document ? this.handleWindowEvent : this.handleEvent, + listenerOptions, + ); + } + } + + _addDefaultHandlers(options: CompleteMapOptions) { + const map = this._map; + const el = map.getCanvasContainer(); + this._add('mapEvent', new MapEventHandler(map, options)); + + const boxZoom = (map.boxZoom = new BoxZoomHandler(map, options)); + this._add('boxZoom', boxZoom); + if (options.interactive && options.boxZoom) { + boxZoom.enable(); + } + + const cooperativeGestures = (map.cooperativeGestures = new CooperativeGesturesHandler( + map, + options.cooperativeGestures, + )); + this._add('cooperativeGestures', cooperativeGestures); + if (options.cooperativeGestures) { + cooperativeGestures.enable(); + } + + const tapZoom = new TapZoomHandler(map); + const clickZoom = new ClickZoomHandler(map); + map.doubleClickZoom = new DoubleClickZoomHandler(clickZoom, tapZoom); + this._add('tapZoom', tapZoom); + this._add('clickZoom', clickZoom); + if (options.interactive && options.doubleClickZoom) { + map.doubleClickZoom.enable(); + } + + const tapDragZoom = new TapDragZoomHandler(); + this._add('tapDragZoom', tapDragZoom); + + const touchPitch = (map.touchPitch = new TwoFingersTouchPitchHandler(map)); + this._add('touchPitch', touchPitch); + if (options.interactive && options.touchPitch) { + map.touchPitch.enable(options.touchPitch); + } + + const mouseRotate = generateMouseRotationHandler(options); + const mousePitch = generateMousePitchHandler(options); + map.dragRotate = new DragRotateHandler(options, mouseRotate, mousePitch); + this._add('mouseRotate', mouseRotate, ['mousePitch']); + this._add('mousePitch', mousePitch, ['mouseRotate']); + if (options.interactive && options.dragRotate) { + map.dragRotate.enable(); + } + + const mousePan = generateMousePanHandler(options); + const touchPan = new TouchPanHandler(options, map); + map.dragPan = new DragPanHandler(el, mousePan, touchPan); + this._add('mousePan', mousePan); + this._add('touchPan', touchPan, ['touchZoom', 'touchRotate']); + if (options.interactive && options.dragPan) { + map.dragPan.enable(options.dragPan); + } + + const touchRotate = new TwoFingersTouchRotateHandler(); + const touchZoom = new TwoFingersTouchZoomHandler(); + map.touchZoomRotate = new TwoFingersTouchZoomRotateHandler( + el, + touchZoom, + touchRotate, + tapDragZoom, + ); + this._add('touchRotate', touchRotate, ['touchPan', 'touchZoom']); + this._add('touchZoom', touchZoom, ['touchPan', 'touchRotate']); + if (options.interactive && options.touchZoomRotate) { + map.touchZoomRotate.enable(options.touchZoomRotate); + } + + const scrollZoom = (map.scrollZoom = new ScrollZoomHandler(map, () => + this._triggerRenderFrame(), + )); + this._add('scrollZoom', scrollZoom, ['mousePan']); + if (options.interactive && options.scrollZoom) { + map.scrollZoom.enable(options.scrollZoom); + } + + const keyboard = (map.keyboard = new KeyboardHandler(map)); + this._add('keyboard', keyboard); + if (options.interactive && options.keyboard) { + map.keyboard.enable(); + } + + this._add('blockableMapEvent', new BlockableMapEventHandler(map)); + } + + _add(handlerName: string, handler: Handler, allowed?: Array) { + this._handlers.push({ handlerName, handler, allowed }); + this._handlersById[handlerName] = handler; + } + + stop(allowEndAnimation: boolean) { + // do nothing if this method was triggered by a gesture update + if (this._updatingCamera) return; + + for (const { handler } of this._handlers) { + handler.reset(); + } + this._inertia.clear(); + this._fireEvents({}, {}, allowEndAnimation); + this._changes = []; + } + + isActive() { + for (const { handler } of this._handlers) { + if (handler.isActive()) return true; + } + return false; + } + + isZooming() { + return !!this._eventsInProgress.zoom || this._map.scrollZoom.isZooming(); + } + isRotating() { + return !!this._eventsInProgress.rotate; + } + + isMoving() { + return Boolean(isMoving(this._eventsInProgress)) || this.isZooming(); + } + + _blockedByActive( + activeHandlers: { [x: string]: Handler }, + allowed: Array, + myName: string, + ) { + for (const name in activeHandlers) { + if (name === myName) continue; + if (!allowed || allowed.indexOf(name) < 0) { + return true; + } + } + return false; + } + + handleWindowEvent = (e: { type: 'mousemove' | 'mouseup' | 'touchmove' }) => { + this.handleEvent(e, `${e.type}Window`); + }; + + _getMapTouches(touches: TouchList) { + const mapTouches = []; + for (const t of touches) { + const target = t.target as any as Node; + if (this._el.contains(target)) { + mapTouches.push(t); + } + } + return mapTouches as any as TouchList; + } + + handleEvent = (e: Event, eventName?: keyof Handler) => { + if (e.type === 'blur') { + this.stop(true); + return; + } + + this._updatingCamera = true; + + const inputEvent = e.type === 'renderFrame' ? undefined : (e as UIEvent); + + /* + * We don't call e.preventDefault() for any events by default. + * Handlers are responsible for calling it where necessary. + */ + + const mergedHandlerResult: HandlerResult = { needsRenderFrame: false }; + const eventsInProgress: EventsInProgress = {}; + const activeHandlers = {}; + const eventTouches = (e as TouchEvent).touches; + + const mapTouches = eventTouches ? this._getMapTouches(eventTouches) : undefined; + const points = mapTouches + ? DOM.touchPos(this._map.getCanvasContainer(), mapTouches) + : DOM.mousePos(this._map.getCanvasContainer(), e as MouseEvent); + + for (const { handlerName, handler, allowed } of this._handlers) { + if (!handler.isEnabled()) continue; + + let data: HandlerResult; + if (this._blockedByActive(activeHandlers, allowed, handlerName)) { + handler.reset(); + } else { + if (handler[eventName || e.type]) { + data = handler[eventName || e.type](e, points, mapTouches); + this.mergeHandlerResult( + mergedHandlerResult, + eventsInProgress, + data, + handlerName, + inputEvent, + ); + if (data && data.needsRenderFrame) { + this._triggerRenderFrame(); + } + } + } + + if (data || handler.isActive()) { + activeHandlers[handlerName] = handler; + } + } + + const deactivatedHandlers: { [handlerName: string]: Event } = {}; + for (const name in this._previousActiveHandlers) { + if (!activeHandlers[name]) { + deactivatedHandlers[name] = inputEvent; + } + } + this._previousActiveHandlers = activeHandlers; + + if (Object.keys(deactivatedHandlers).length || hasChange(mergedHandlerResult)) { + this._changes.push([mergedHandlerResult, eventsInProgress, deactivatedHandlers]); + this._triggerRenderFrame(); + } + + if (Object.keys(activeHandlers).length || hasChange(mergedHandlerResult)) { + this._map._stop(true); + } + + this._updatingCamera = false; + + const { cameraAnimation } = mergedHandlerResult; + if (cameraAnimation) { + this._inertia.clear(); + this._fireEvents({}, {}, true); + this._changes = []; + cameraAnimation(this._map); + } + }; + + mergeHandlerResult( + mergedHandlerResult: HandlerResult, + eventsInProgress: EventsInProgress, + handlerResult: HandlerResult, + name: string, + e?: UIEvent, + ) { + if (!handlerResult) return; + + extend(mergedHandlerResult, handlerResult); + + const eventData = { handlerName: name, originalEvent: handlerResult.originalEvent || e }; + + // track which handler changed which camera property + if (handlerResult.zoomDelta !== undefined) { + eventsInProgress.zoom = eventData; + } + if (handlerResult.panDelta !== undefined) { + eventsInProgress.drag = eventData; + } + if (handlerResult.pitchDelta !== undefined) { + eventsInProgress.pitch = eventData; + } + if (handlerResult.bearingDelta !== undefined) { + eventsInProgress.rotate = eventData; + } + } + + _applyChanges() { + const combined: HandlerResult = {}; + const combinedEventsInProgress: EventsInProgress = {}; + const combinedDeactivatedHandlers = {}; + + for (const [change, eventsInProgress, deactivatedHandlers] of this._changes) { + if (change.panDelta) + combined.panDelta = (combined.panDelta || new Point(0, 0))._add(change.panDelta); + if (change.zoomDelta) combined.zoomDelta = (combined.zoomDelta || 0) + change.zoomDelta; + if (change.bearingDelta) + combined.bearingDelta = (combined.bearingDelta || 0) + change.bearingDelta; + if (change.pitchDelta) combined.pitchDelta = (combined.pitchDelta || 0) + change.pitchDelta; + if (change.around !== undefined) combined.around = change.around; + if (change.pinchAround !== undefined) combined.pinchAround = change.pinchAround; + if (change.noInertia) combined.noInertia = change.noInertia; + + extend(combinedEventsInProgress, eventsInProgress); + extend(combinedDeactivatedHandlers, deactivatedHandlers); + } + + this._updateMapTransform(combined, combinedEventsInProgress, combinedDeactivatedHandlers); + this._changes = []; + } + + _updateMapTransform( + combinedResult: HandlerResult, + combinedEventsInProgress: EventsInProgress, + deactivatedHandlers: { [handlerName: string]: Event }, + ) { + const map = this._map; + const tr = map._getTransformForUpdate(); + + if (!hasChange(combinedResult)) { + return this._fireEvents(combinedEventsInProgress, deactivatedHandlers, true); + } + + const { panDelta, zoomDelta, bearingDelta, pitchDelta, pinchAround } = combinedResult; + let { around } = combinedResult; + + if (pinchAround !== undefined) { + around = pinchAround; + } + + // stop any ongoing camera animations (easeTo, flyTo) + map._stop(true); + + around = around || map.transform.centerPoint; + const loc = tr.pointLocation(panDelta ? around.sub(panDelta) : around); + if (bearingDelta) tr.bearing += bearingDelta; + if (pitchDelta) tr.pitch += pitchDelta; + if (zoomDelta) tr.zoom += zoomDelta; + + tr.setLocationAtPoint(loc, around); + + map._applyUpdatedTransform(tr); + + this._map._update(); + if (!combinedResult.noInertia) this._inertia.record(combinedResult); + this._fireEvents(combinedEventsInProgress, deactivatedHandlers, true); + } + + _fireEvents( + newEventsInProgress: EventsInProgress, + deactivatedHandlers: { [handlerName: string]: Event }, + allowEndAnimation: boolean, + ) { + const wasMoving = isMoving(this._eventsInProgress); + const nowMoving = isMoving(newEventsInProgress); + + const startEvents = {}; + + for (const eventName in newEventsInProgress) { + const { originalEvent } = newEventsInProgress[eventName]; + if (!this._eventsInProgress[eventName]) { + startEvents[`${eventName}start`] = originalEvent; + } + this._eventsInProgress[eventName] = newEventsInProgress[eventName]; + } + + // fire start events only after this._eventsInProgress has been updated + if (!wasMoving && nowMoving) { + this._fireEvent('movestart', nowMoving.originalEvent); + } + + for (const name in startEvents) { + this._fireEvent(name, startEvents[name]); + } + + if (nowMoving) { + this._fireEvent('move', nowMoving.originalEvent); + } + + for (const eventName in newEventsInProgress) { + const { originalEvent } = newEventsInProgress[eventName]; + this._fireEvent(eventName, originalEvent); + } + + const endEvents = {}; + + let originalEndEvent; + for (const eventName in this._eventsInProgress) { + const { handlerName, originalEvent } = this._eventsInProgress[eventName]; + if (!this._handlersById[handlerName].isActive()) { + delete this._eventsInProgress[eventName]; + originalEndEvent = deactivatedHandlers[handlerName] || originalEvent; + endEvents[`${eventName}end`] = originalEndEvent; + } + } + + for (const name in endEvents) { + this._fireEvent(name, endEvents[name]); + } + + const stillMoving = isMoving(this._eventsInProgress); + const finishedMoving = (wasMoving || nowMoving) && !stillMoving; + if (allowEndAnimation && finishedMoving) { + this._updatingCamera = true; + const inertialEase = this._inertia._onMoveEnd(this._map.dragPan._inertiaOptions); + + const shouldSnapToNorth = (bearing) => + bearing !== 0 && -this._bearingSnap < bearing && bearing < this._bearingSnap; + + if (inertialEase && (inertialEase.essential || !browser.prefersReducedMotion)) { + if (shouldSnapToNorth(inertialEase.bearing || this._map.getBearing())) { + inertialEase.bearing = 0; + } + inertialEase.freezeElevation = true; + this._map.easeTo(inertialEase, { originalEvent: originalEndEvent }); + } else { + this._map.fire(new Event('moveend', { originalEvent: originalEndEvent })); + if (shouldSnapToNorth(this._map.getBearing())) { + this._map.resetNorth(); + } + } + this._updatingCamera = false; + } + } + + _fireEvent(type: string, e?: Event) { + this._map.fire(new Event(type, e ? { originalEvent: e } : {})); + } + + _requestFrame() { + this._map.triggerRepaint(); + return this._map._renderTaskQueue.add((timeStamp) => { + delete this._frameId; + this.handleEvent(new RenderFrameEvent('renderFrame', timeStamp)); + this._applyChanges(); + }); + } + + _triggerRenderFrame() { + if (this._frameId === undefined) { + this._frameId = this._requestFrame(); + } + } +} diff --git a/packages/map/src/map/map.ts b/packages/map/src/map/map.ts new file mode 100644 index 00000000000..83ee8707638 --- /dev/null +++ b/packages/map/src/map/map.ts @@ -0,0 +1,1039 @@ +import Point from '@mapbox/point-geometry'; +import { Camera } from './camera'; +import type { MapEventType } from './events'; +import { LngLat } from './geo/lng_lat'; +import { LngLatBounds } from './geo/lng_lat_bounds'; +import { Transform } from './geo/transform'; +import { HandlerManager } from './handler_manager'; +import { browser } from './util/browser'; +import { DOM } from './util/dom'; +import type { Listener } from './util/evented'; +import { Event } from './util/evented'; +import { TaskQueue } from './util/task_queue'; +import type { Complete } from './util/util'; +import { extend, uniqueId } from './util/util'; + +import './css/l7.css'; + +import { lodashUtil } from '@antv/l7-utils'; +import type { CameraOptions, FitBoundsOptions, PointLike } from './camera'; +import type { LngLatLike } from './geo/lng_lat'; +import type { LngLatBoundsLike } from './geo/lng_lat_bounds'; +import type { BoxZoomHandler } from './handler/box_zoom'; +import type { CooperativeGesturesHandler, GestureOptions } from './handler/cooperative_gestures'; +import type { KeyboardHandler } from './handler/keyboard'; +import type { ScrollZoomHandler } from './handler/scroll_zoom'; +import type { DoubleClickZoomHandler } from './handler/shim/dblclick_zoom'; +import type { DragPanHandler, DragPanOptions } from './handler/shim/drag_pan'; +import type { DragRotateHandler } from './handler/shim/drag_rotate'; +import type { TwoFingersTouchZoomRotateHandler } from './handler/shim/two_fingers_touch'; +import type { AroundCenterOptions, TwoFingersTouchPitchHandler } from './handler/two_fingers_touch'; +import type { TaskID } from './util/task_queue'; + +/** + * The {@link Map} options object. + */ +export type MapOptions = { + /** + * If `false`, no mouse, touch, or keyboard listeners will be attached to the map, so it will not respond to interaction. + * @defaultValue true + */ + interactive?: boolean; + /** + * The HTML element in which MapLibre GL JS will render the map, or the element's string `id`. The specified element must have no children. + */ + container: HTMLElement | string; + /** + * The threshold, measured in degrees, that determines when the map's + * bearing will snap to north. For example, with a `bearingSnap` of 7, if the user rotates + * the map within 7 degrees of north, the map will automatically snap to exact north. + * @defaultValue 7 + */ + bearingSnap?: number; + /** + * If set, the map will be constrained to the given bounds. + */ + maxBounds?: LngLatBoundsLike; + /** + * If `true`, the "scroll to zoom" interaction is enabled. {@link AroundCenterOptions} are passed as options to {@link ScrollZoomHandler#enable}. + * @defaultValue true + */ + scrollZoom?: boolean | AroundCenterOptions; + /** + * The minimum zoom level of the map (0-24). + * @defaultValue 0 + */ + minZoom?: number | null; + /** + * The maximum zoom level of the map (0-24). + * @defaultValue 22 + */ + maxZoom?: number | null; + /** + * The minimum pitch of the map (0-85). Values greater than 60 degrees are experimental and may result in rendering issues. If you encounter any, please raise an issue with details in the MapLibre project. + * @defaultValue 0 + */ + minPitch?: number | null; + /** + * The maximum pitch of the map (0-85). Values greater than 60 degrees are experimental and may result in rendering issues. If you encounter any, please raise an issue with details in the MapLibre project. + * @defaultValue 60 + */ + maxPitch?: number | null; + /** + * If `true`, the "box zoom" interaction is enabled (see {@link BoxZoomHandler}). + * @defaultValue true + */ + boxZoom?: boolean; + /** + * If `true`, the "drag to rotate" interaction is enabled (see {@link DragRotateHandler}). + * @defaultValue true + */ + dragRotate?: boolean; + /** + * If `true`, the "drag to pan" interaction is enabled. An `Object` value is passed as options to {@link DragPanHandler#enable}. + * @defaultValue true + */ + dragPan?: boolean | DragPanOptions; + /** + * If `true`, keyboard shortcuts are enabled (see {@link KeyboardHandler}). + * @defaultValue true + */ + keyboard?: boolean; + /** + * If `true`, the "double click to zoom" interaction is enabled (see {@link DoubleClickZoomHandler}). + * @defaultValue true + */ + doubleClickZoom?: boolean; + /** + * If `true`, the "pinch to rotate and zoom" interaction is enabled. An `Object` value is passed as options to {@link TwoFingersTouchZoomRotateHandler#enable}. + * @defaultValue true + */ + touchZoomRotate?: boolean | AroundCenterOptions; + /** + * If `true`, the "drag to pitch" interaction is enabled. An `Object` value is passed as options to {@link TwoFingersTouchPitchHandler#enable}. + * @defaultValue true + */ + touchPitch?: boolean | AroundCenterOptions; + /** + * If `true` or set to an options object, the map is only accessible on desktop while holding Command/Ctrl and only accessible on mobile with two fingers. Interacting with the map using normal gestures will trigger an informational screen. With this option enabled, "drag to pitch" requires a three-finger gesture. Cooperative gestures are disabled when a map enters fullscreen using {@link FullscreenControl}. + * @defaultValue false + */ + cooperativeGestures?: GestureOptions; + /** + * If `true`, the map will automatically resize when the browser window resizes. + * @defaultValue true + */ + trackResize?: boolean; + /** + * The initial geographical centerpoint of the map. If `center` is not specified in the constructor options, MapLibre GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `[0, 0]` Note: MapLibre GL JS uses longitude, latitude coordinate order (as opposed to latitude, longitude) to match GeoJSON. + * @defaultValue [0, 0] + */ + center?: LngLatLike; + /** + * The initial zoom level of the map. If `zoom` is not specified in the constructor options, MapLibre GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `0`. + * @defaultValue 0 + */ + zoom?: number; + /** + * The initial bearing (rotation) of the map, measured in degrees counter-clockwise from north. If `bearing` is not specified in the constructor options, MapLibre GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `0`. + * @defaultValue 0 + */ + bearing?: number; + /** + * The initial pitch (tilt) of the map, measured in degrees away from the plane of the screen (0-85). If `pitch` is not specified in the constructor options, MapLibre GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `0`. Values greater than 60 degrees are experimental and may result in rendering issues. If you encounter any, please raise an issue with details in the MapLibre project. + * @defaultValue 0 + */ + pitch?: number; + /** + * If `true`, multiple copies of the world will be rendered side by side beyond -180 and 180 degrees longitude. If set to `false`: + * + * - When the map is zoomed out far enough that a single representation of the world does not fill the map's entire + * container, there will be blank space beyond 180 and -180 degrees longitude. + * - Features that cross 180 and -180 degrees longitude will be cut in two (with one portion on the right edge of the + * map and the other on the left edge of the map) at every zoom level. + * @defaultValue true + */ + renderWorldCopies?: boolean; + /** + * Controls the duration of the fade-in/fade-out animation for label collisions after initial map load, in milliseconds. This setting affects all symbol layers. This setting does not affect the duration of runtime styling transitions or raster tile cross-fading. + * @defaultValue 300 + */ + fadeDuration?: number; + /** + * The max number of pixels a user can shift the mouse pointer during a click for it to be considered a valid click (as opposed to a mouse drag). + * @defaultValue 3 + */ + clickTolerance?: number; + /** + * The initial bounds of the map. If `bounds` is specified, it overrides `center` and `zoom` constructor options. + */ + bounds?: LngLatBoundsLike; + /** + * A {@link FitBoundsOptions} options object to use _only_ when fitting the initial `bounds` provided above. + */ + fitBoundsOptions?: FitBoundsOptions; + /** + * If `false`, the map's pitch (tilt) control with "drag to rotate" interaction will be disabled. + * @defaultValue true + */ + pitchWithRotate?: boolean; +}; + +// This type is used inside map since all properties are assigned a default value. +export type CompleteMapOptions = Complete; + +const defaultMinZoom = -2; +const defaultMaxZoom = 22; + +// the default values, but also the valid range +const defaultMinPitch = 0; +const defaultMaxPitch = 60; + +// use this variable to check maxPitch for validity +const maxPitchThreshold = 85; + +const defaultOptions: Readonly> = { + interactive: true, + bearingSnap: 7, + + scrollZoom: true, + minZoom: defaultMinZoom, + maxZoom: defaultMaxZoom, + minPitch: defaultMinPitch, + maxPitch: defaultMaxPitch, + + boxZoom: true, + dragRotate: true, + dragPan: true, + keyboard: true, + doubleClickZoom: true, + touchZoomRotate: true, + touchPitch: true, + cooperativeGestures: false, + + trackResize: true, + + center: [0, 0], + zoom: 0, + bearing: 0, + pitch: 0, + + renderWorldCopies: true, + fadeDuration: 300, + clickTolerance: 3, + pitchWithRotate: true, +}; + +/** + * The `Map` object represents the map on your page. It exposes methods + * and properties that enable you to programmatically change the map, + * and fires events as users interact with it. + * + * You create a `Map` by specifying a `container` and other options, see {@link MapOptions} for the full list. + * Then MapLibre GL JS initializes the map on the page and returns your `Map` object. + * + * @group Main + * + * @example + * ```ts + * let map = new Map({ + * container: 'map', + * center: [-122.420679, 37.772537], + * zoom: 13, + * }); + * ``` + */ +export class Map extends Camera { + _container: HTMLElement; + _canvasContainer: HTMLElement; + _interactive: boolean; + _frameRequest: AbortController; + + _loaded: boolean; + _idleTriggered = false; + // accounts for placement finishing as well + _fullyLoaded: boolean; + _trackResize: boolean; + _resizeObserver: ResizeObserver; + _preserveDrawingBuffer: boolean; + _failIfMajorPerformanceCaveat: boolean; + _fadeDuration: number; + _crossSourceCollisions: boolean; + _crossFadingFactor = 1; + _collectResourceTiming: boolean; + _renderTaskQueue = new TaskQueue(); + _mapId = uniqueId(); + _removed: boolean; + _clickTolerance: number; + + /** + * The map's {@link ScrollZoomHandler}, which implements zooming in and out with a scroll wheel or trackpad. + * Find more details and examples using `scrollZoom` in the {@link ScrollZoomHandler} section. + */ + scrollZoom: ScrollZoomHandler; + + /** + * The map's {@link BoxZoomHandler}, which implements zooming using a drag gesture with the Shift key pressed. + * Find more details and examples using `boxZoom` in the {@link BoxZoomHandler} section. + */ + boxZoom: BoxZoomHandler; + + /** + * The map's {@link DragRotateHandler}, which implements rotating the map while dragging with the right + * mouse button or with the Control key pressed. Find more details and examples using `dragRotate` + * in the {@link DragRotateHandler} section. + */ + dragRotate: DragRotateHandler; + + /** + * The map's {@link DragPanHandler}, which implements dragging the map with a mouse or touch gesture. + * Find more details and examples using `dragPan` in the {@link DragPanHandler} section. + */ + dragPan: DragPanHandler; + + /** + * The map's {@link KeyboardHandler}, which allows the user to zoom, rotate, and pan the map using keyboard + * shortcuts. Find more details and examples using `keyboard` in the {@link KeyboardHandler} section. + */ + keyboard: KeyboardHandler; + + /** + * The map's {@link DoubleClickZoomHandler}, which allows the user to zoom by double clicking. + * Find more details and examples using `doubleClickZoom` in the {@link DoubleClickZoomHandler} section. + */ + doubleClickZoom: DoubleClickZoomHandler; + + /** + * The map's {@link TwoFingersTouchZoomRotateHandler}, which allows the user to zoom or rotate the map with touch gestures. + * Find more details and examples using `touchZoomRotate` in the {@link TwoFingersTouchZoomRotateHandler} section. + */ + touchZoomRotate: TwoFingersTouchZoomRotateHandler; + + /** + * The map's {@link TwoFingersTouchPitchHandler}, which allows the user to pitch the map with touch gestures. + * Find more details and examples using `touchPitch` in the {@link TwoFingersTouchPitchHandler} section. + */ + touchPitch: TwoFingersTouchPitchHandler; + + /** + * The map's {@link CooperativeGesturesHandler}, which allows the user to see cooperative gesture info when user tries to zoom in/out. + * Find more details and examples using `cooperativeGestures` in the {@link CooperativeGesturesHandler} section. + */ + cooperativeGestures: CooperativeGesturesHandler; + + constructor(options: MapOptions) { + const resolvedOptions = { ...defaultOptions, ...options } as CompleteMapOptions; + + if ( + resolvedOptions.minZoom != null && + resolvedOptions.maxZoom != null && + resolvedOptions.minZoom > resolvedOptions.maxZoom + ) { + throw new Error('maxZoom must be greater than or equal to minZoom'); + } + + if ( + resolvedOptions.minPitch != null && + resolvedOptions.maxPitch != null && + resolvedOptions.minPitch > resolvedOptions.maxPitch + ) { + throw new Error('maxPitch must be greater than or equal to minPitch'); + } + + if (resolvedOptions.minPitch != null && resolvedOptions.minPitch < defaultMinPitch) { + throw new Error(`minPitch must be greater than or equal to ${defaultMinPitch}`); + } + + if (resolvedOptions.maxPitch != null && resolvedOptions.maxPitch > maxPitchThreshold) { + throw new Error(`maxPitch must be less than or equal to ${maxPitchThreshold}`); + } + + const transform = new Transform( + resolvedOptions.minZoom!, + resolvedOptions.maxZoom!, + resolvedOptions.minPitch!, + resolvedOptions.maxPitch!, + resolvedOptions.renderWorldCopies, + ); + super(transform, { bearingSnap: resolvedOptions.bearingSnap! }); + + this._interactive = resolvedOptions.interactive!; + this._trackResize = resolvedOptions.trackResize === true; + this._bearingSnap = resolvedOptions.bearingSnap!; + this._fadeDuration = resolvedOptions.fadeDuration!; + this._clickTolerance = resolvedOptions.clickTolerance!; + + if (typeof resolvedOptions.container === 'string') { + this._container = document.getElementById(resolvedOptions.container)!; + if (!this._container) { + throw new Error(`Container '${resolvedOptions.container}' not found.`); + } + } else if (resolvedOptions.container instanceof HTMLElement) { + this._container = resolvedOptions.container; + } else { + throw new Error("Invalid type: 'container' must be a String or HTMLElement."); + } + + if (resolvedOptions.maxBounds) { + this.setMaxBounds(resolvedOptions.maxBounds); + } + + this._setupContainer(); + + this.on('move', () => this._update()) + .on('moveend', () => this._update()) + .on('zoom', () => this._update()) + .once('idle', () => { + this._idleTriggered = true; + }); + + if (typeof window !== 'undefined') { + let initialResizeEventCaptured = false; + const throttledResizeCallback = lodashUtil.throttle((entries: ResizeObserverEntry[]) => { + if (this._trackResize && !this._removed) { + this.resize(entries)._update(); + } + }, 50); + this._resizeObserver = new ResizeObserver((entries) => { + if (!initialResizeEventCaptured) { + initialResizeEventCaptured = true; + return; + } + throttledResizeCallback(entries); + }); + this._resizeObserver.observe(this._container); + } + + this.handlers = new HandlerManager(this, resolvedOptions); + + this.jumpTo({ + center: resolvedOptions.center, + zoom: resolvedOptions.zoom, + bearing: resolvedOptions.bearing, + pitch: resolvedOptions.pitch, + }); + + if (resolvedOptions.bounds) { + this.resize(); + this.fitBounds( + resolvedOptions.bounds, + extend({}, resolvedOptions.fitBoundsOptions, { duration: 0 }), + ); + } + + this.resize(); + } + + /** + * @internal + * Returns a unique number for this map instance which is used for the MapLoadEvent + * to make sure we only fire one event per instantiated map object. + * @returns the uniq map ID + */ + _getMapId() { + return this._mapId; + } + + calculateCameraOptionsFromTo( + from: LngLat, + altitudeFrom: number, + to: LngLat, + altitudeTo?: number, + ): CameraOptions { + return super.calculateCameraOptionsFromTo(from, altitudeFrom, to, altitudeTo); + } + + /** + * Resizes the map according to the dimensions of its + * `container` element. + * + * Checks if the map container size changed and updates the map if it has changed. + * This method must be called after the map's `container` is resized programmatically + * or when the map is shown after being initially hidden with CSS. + * + * Triggers the following events: `movestart`, `move`, `moveend`, and `resize`. + * + * @param eventData - Additional properties to be passed to `movestart`, `move`, `resize`, and `moveend` + * events that get triggered as a result of resize. This can be useful for differentiating the + * source of an event (for example, user-initiated or programmatically-triggered events). + * @example + * Resize the map when the map container is shown after being initially hidden with CSS. + * ```ts + * let mapDiv = document.getElementById('map'); + * if (mapDiv.style.visibility === true) map.resize(); + * ``` + */ + resize(eventData?: any): Map { + const dimensions = this._containerDimensions(); + const width = dimensions[0]; + const height = dimensions[1]; + + this.transform.resize(width, height); + this._requestedCameraState?.resize(width, height); + + const fireMoving = !this._moving; + if (fireMoving) { + this.stop(); + this.fire(new Event('movestart', eventData)).fire(new Event('move', eventData)); + } + + this.fire(new Event('resize', eventData)); + + if (fireMoving) this.fire(new Event('moveend', eventData)); + + return this; + } + + /** + * Returns the map's geographical bounds. When the bearing or pitch is non-zero, the visible region is not + * an axis-aligned rectangle, and the result is the smallest bounds that encompasses the visible region. + * @returns The geographical bounds of the map as {@link LngLatBounds}. + * @example + * ```ts + * let bounds = map.getBounds(); + * ``` + */ + getBounds(): LngLatBounds { + return this.transform.getBounds(); + } + + /** + * Returns the maximum geographical bounds the map is constrained to, or `null` if none set. + * @returns The map object. + * @example + * ```ts + * let maxBounds = map.getMaxBounds(); + * ``` + */ + getMaxBounds(): LngLatBounds | null { + return this.transform.getMaxBounds(); + } + + /** + * Sets or clears the map's geographical bounds. + * + * Pan and zoom operations are constrained within these bounds. + * If a pan or zoom is performed that would + * display regions outside these bounds, the map will + * instead display a position and zoom level + * as close as possible to the operation's request while still + * remaining within the bounds. + * + * @param bounds - The maximum bounds to set. If `null` or `undefined` is provided, the function removes the map's maximum bounds. + * @example + * Define bounds that conform to the `LngLatBoundsLike` object as set the max bounds. + * ```ts + * let bounds = [ + * [-74.04728, 40.68392], // [west, south] + * [-73.91058, 40.87764] // [east, north] + * ]; + * map.setMaxBounds(bounds); + * ``` + */ + setMaxBounds(bounds?: LngLatBoundsLike | null): Map { + this.transform.setMaxBounds(bounds && LngLatBounds.convert(bounds)); + return this._update(); + } + + /** + * Sets or clears the map's minimum zoom level. + * If the map's current zoom level is lower than the new minimum, + * the map will zoom to the new minimum. + * + * It is not always possible to zoom out and reach the set `minZoom`. + * Other factors such as map height may restrict zooming. For example, + * if the map is 512px tall it will not be possible to zoom below zoom 0 + * no matter what the `minZoom` is set to. + * + * A {@link ErrorEvent} event will be fired if minZoom is out of bounds. + * + * @param minZoom - The minimum zoom level to set (-2 - 24). + * If `null` or `undefined` is provided, the function removes the current minimum zoom (i.e. sets it to -2). + * @example + * ```ts + * map.setMinZoom(12.25); + * ``` + */ + setMinZoom(minZoom?: number | null): Map { + minZoom = minZoom === null || minZoom === undefined ? defaultMinZoom : minZoom; + + if (minZoom >= defaultMinZoom && minZoom <= this.transform.maxZoom) { + this.transform.minZoom = minZoom; + this._update(); + + if (this.getZoom() < minZoom) this.setZoom(minZoom); + + return this; + } else + throw new Error( + `minZoom must be between ${defaultMinZoom} and the current maxZoom, inclusive`, + ); + } + + /** + * Returns the map's minimum allowable zoom level. + * + * @returns minZoom + * @example + * ```ts + * let minZoom = map.getMinZoom(); + * ``` + */ + getMinZoom(): number { + return this.transform.minZoom; + } + + /** + * Sets or clears the map's maximum zoom level. + * If the map's current zoom level is higher than the new maximum, + * the map will zoom to the new maximum. + * + * A {@link ErrorEvent} event will be fired if minZoom is out of bounds. + * + * @param maxZoom - The maximum zoom level to set. + * If `null` or `undefined` is provided, the function removes the current maximum zoom (sets it to 22). + * @example + * ```ts + * map.setMaxZoom(18.75); + * ``` + */ + setMaxZoom(maxZoom?: number | null): Map { + maxZoom = maxZoom === null || maxZoom === undefined ? defaultMaxZoom : maxZoom; + + if (maxZoom >= this.transform.minZoom) { + this.transform.maxZoom = maxZoom; + + if (this.getZoom() > maxZoom) this.setZoom(maxZoom); + + return this; + } else throw new Error('maxZoom must be greater than the current minZoom'); + } + + /** + * Returns the map's maximum allowable zoom level. + * + * @returns The maxZoom + * @example + * ```ts + * let maxZoom = map.getMaxZoom(); + * ``` + */ + getMaxZoom(): number { + return this.transform.maxZoom; + } + + /** + * Sets or clears the map's minimum pitch. + * If the map's current pitch is lower than the new minimum, + * the map will pitch to the new minimum. + * + * A {@link ErrorEvent} event will be fired if minPitch is out of bounds. + * + * @param minPitch - The minimum pitch to set (0-85). Values greater than 60 degrees are experimental and may result in rendering issues. If you encounter any, please raise an issue with details in the MapLibre project. + * If `null` or `undefined` is provided, the function removes the current minimum pitch (i.e. sets it to 0). + */ + setMinPitch(minPitch?: number | null): Map { + minPitch = minPitch === null || minPitch === undefined ? defaultMinPitch : minPitch; + + if (minPitch < defaultMinPitch) { + throw new Error(`minPitch must be greater than or equal to ${defaultMinPitch}`); + } + + if (minPitch >= defaultMinPitch && minPitch <= this.transform.maxPitch) { + this.transform.minPitch = minPitch; + + if (this.getPitch() < minPitch) this.setPitch(minPitch); + + return this; + } else + throw new Error( + `minPitch must be between ${defaultMinPitch} and the current maxPitch, inclusive`, + ); + } + + /** + * Returns the map's minimum allowable pitch. + * + * @returns The minPitch + */ + getMinPitch(): number { + return this.transform.minPitch; + } + + /** + * Sets or clears the map's maximum pitch. + * If the map's current pitch is higher than the new maximum, + * the map will pitch to the new maximum. + * + * A {@link ErrorEvent} event will be fired if maxPitch is out of bounds. + * + * @param maxPitch - The maximum pitch to set (0-85). Values greater than 60 degrees are experimental and may result in rendering issues. If you encounter any, please raise an issue with details in the MapLibre project. + * If `null` or `undefined` is provided, the function removes the current maximum pitch (sets it to 60). + */ + setMaxPitch(maxPitch?: number | null): Map { + maxPitch = maxPitch === null || maxPitch === undefined ? defaultMaxPitch : maxPitch; + + if (maxPitch > maxPitchThreshold) { + throw new Error(`maxPitch must be less than or equal to ${maxPitchThreshold}`); + } + + if (maxPitch >= this.transform.minPitch) { + this.transform.maxPitch = maxPitch; + + if (this.getPitch() > maxPitch) this.setPitch(maxPitch); + + return this; + } else throw new Error('maxPitch must be greater than the current minPitch'); + } + + /** + * Returns the map's maximum allowable pitch. + * + * @returns The maxPitch + */ + getMaxPitch(): number { + return this.transform.maxPitch; + } + + /** + * Returns the state of `renderWorldCopies`. If `true`, multiple copies of the world will be rendered side by side beyond -180 and 180 degrees longitude. If set to `false`: + * + * - When the map is zoomed out far enough that a single representation of the world does not fill the map's entire + * container, there will be blank space beyond 180 and -180 degrees longitude. + * - Features that cross 180 and -180 degrees longitude will be cut in two (with one portion on the right edge of the + * map and the other on the left edge of the map) at every zoom level. + * @returns The renderWorldCopies + * @example + * ```ts + * let worldCopiesRendered = map.getRenderWorldCopies(); + * ``` + * @see [Render world copies](https://maplibre.org/maplibre-gl-js/docs/examples/render-world-copies/) + */ + getRenderWorldCopies(): boolean { + return this.transform.renderWorldCopies; + } + + /** + * Sets the state of `renderWorldCopies`. + * + * @param renderWorldCopies - If `true`, multiple copies of the world will be rendered side by side beyond -180 and 180 degrees longitude. If set to `false`: + * + * - When the map is zoomed out far enough that a single representation of the world does not fill the map's entire + * container, there will be blank space beyond 180 and -180 degrees longitude. + * - Features that cross 180 and -180 degrees longitude will be cut in two (with one portion on the right edge of the + * map and the other on the left edge of the map) at every zoom level. + * + * `undefined` is treated as `true`, `null` is treated as `false`. + * @example + * ```ts + * map.setRenderWorldCopies(true); + * ``` + */ + setRenderWorldCopies(renderWorldCopies?: boolean | null) { + this.transform.renderWorldCopies = renderWorldCopies; + } + + /** + * Returns a [Point](https://github.com/mapbox/point-geometry) representing pixel coordinates, relative to the map's `container`, + * that correspond to the specified geographical location. + * + * @param lnglat - The geographical location to project. + * @returns The [Point](https://github.com/mapbox/point-geometry) corresponding to `lnglat`, relative to the map's `container`. + * @example + * ```ts + * let coordinate = [-122.420679, 37.772537]; + * let point = map.project(coordinate); + * ``` + */ + project(lnglat: LngLatLike): Point { + return this.transform.locationPoint(LngLat.convert(lnglat)); + } + + /** + * Returns a {@link LngLat} representing geographical coordinates that correspond + * to the specified pixel coordinates. + * + * @param point - The pixel coordinates to unproject. + * @returns The {@link LngLat} corresponding to `point`. + * @example + * ```ts + * map.on('click', (e) => { + * // When the map is clicked, get the geographic coordinate. + * let coordinate = map.unproject(e.point); + * }); + * ``` + */ + unproject(point: PointLike): LngLat { + return this.transform.pointLocation(Point.convert(point)); + } + + /** + * Returns true if the map is panning, zooming, rotating, or pitching due to a camera animation or user gesture. + * @returns true if the map is moving. + * @example + * ```ts + * let isMoving = map.isMoving(); + * ``` + */ + isMoving(): boolean { + return this._moving || this.handlers?.isMoving(); + } + + /** + * Returns true if the map is zooming due to a camera animation or user gesture. + * @returns true if the map is zooming. + * @example + * ```ts + * let isZooming = map.isZooming(); + * ``` + */ + isZooming(): boolean { + return this._zooming || this.handlers?.isZooming(); + } + + /** + * Returns true if the map is rotating due to a camera animation or user gesture. + * @returns true if the map is rotating. + * @example + * ```ts + * map.isRotating(); + * ``` + */ + isRotating(): boolean { + return this._rotating || this.handlers?.isRotating(); + } + + /** + * Overload of the `on` method that allows to listen to events without specifying a layer. + * @event + * @param type - The type of the event. + * @param listener - The listener callback. + */ + on(type: T, listener: (ev: MapEventType[T] & Object) => void): this; + /** + * Overload of the `on` method that allows to listen to events without specifying a layer. + * @event + * @param type - The type of the event. + * @param listener - The listener callback. + */ + on(type: keyof MapEventType | string, listener: Listener): this; + on(type: keyof MapEventType | string, listener: Listener): this { + return super.on(type, listener); + } + + /** + * Overload of the `once` method that allows to listen to events without specifying a layer. + * @event + * @param type - The type of the event. + * @param listener - The listener callback. + */ + once( + type: T, + listener?: (ev: MapEventType[T] & Object) => void, + ): this | Promise; + /** + * Overload of the `once` method that allows to listen to events without specifying a layer. + * @event + * @param type - The type of the event. + * @param listener - The listener callback. + */ + once(type: keyof MapEventType | string, listener?: Listener): this | Promise; + once(type: keyof MapEventType | string, listener?: Listener): this | Promise { + return super.once(type, listener); + } + + /** + * Overload of the `off` method that allows to listen to events without specifying a layer. + * @event + * @param type - The type of the event. + * @param listener - The function previously installed as a listener. + */ + off( + type: T, + listener: (ev: MapEventType[T] & Object) => void, + ): this; + /** + * Overload of the `off` method that allows to listen to events without specifying a layer. + * @event + * @param type - The type of the event. + * @param listener - The function previously installed as a listener. + */ + off(type: keyof MapEventType | string, listener: Listener): this; + off(type: keyof MapEventType | string, listener: Listener): this { + return super.off(type, listener); + } + + /** + * Returns the map's containing HTML element. + * + * @returns The map's container. + */ + getContainer(): HTMLElement { + return this._container; + } + + /** + * Returns the HTML element containing the map's `` element. + * + * If you want to add non-GL overlays to the map, you should append them to this element. + * + * This is the element to which event bindings for map interactivity (such as panning and zooming) are + * attached. It will receive bubbled events from child elements such as the ``, but not from + * map controls. + * + * @returns The container of the map's ``. + * @see [Create a draggable point](https://maplibre.org/maplibre-gl-js/docs/examples/drag-a-point/) + */ + getCanvasContainer(): HTMLElement { + return this._canvasContainer; + } + + _containerDimensions() { + let width = 0; + let height = 0; + + if (this._container) { + width = this._container.clientWidth || 400; + height = this._container.clientHeight || 300; + } + + return [width, height]; + } + + _setupContainer() { + const container = this._container; + container.classList.add('l7-map'); + + const canvasContainer = (this._canvasContainer = DOM.create( + 'div', + 'l7-canvas-container', + container, + )); + if (this._interactive) { + canvasContainer.classList.add('l7-interactive'); + } + + this._container.addEventListener('scroll', this._onMapScroll, false); + } + + _onMapScroll = (event: any) => { + if (event.target !== this._container) return; + + // Revert any scroll which would move the canvas outside of the view + this._container.scrollTop = 0; + this._container.scrollLeft = 0; + return false; + }; + + /** + * @internal + * Update this map's style and sources, and re-render the map. + * + * @param updateStyle - mark the map's style for reprocessing as + * well as its sources + */ + _update() { + this.triggerRepaint(); + + return this; + } + + /** + * @internal + * Request that the given callback be executed during the next render + * frame. Schedule a render frame if one is not already scheduled. + * + * @returns An id that can be used to cancel the callback + */ + _requestRenderFrame(callback: () => void): TaskID { + this._update(); + return this._renderTaskQueue.add(callback); + } + + _cancelRenderFrame(id: TaskID) { + this._renderTaskQueue.remove(id); + } + + /** + * @internal + * Call when a (re-)render of the map is required: + * + * - The style has changed (`setPaintProperty()`, etc.) + * - Source data has changed (e.g. tiles have finished loading) + * - The map has is moving (or just finished moving) + * - A transition is in progress + * + * @param paintStartTimeStamp - The time when the animation frame began executing. + */ + _render(paintStartTimeStamp: number) { + this._renderTaskQueue.run(paintStartTimeStamp); + // A task queue callback may have fired a user event which may have removed the map + if (this._removed) return; + + this.fire(new Event('render')); + + if (!this.isMoving()) { + this.fire(new Event('idle')); + } + + return this; + } + + /** + * Clean up and release all internal resources associated with this map. + * + * This includes DOM elements, event bindings, web workers, and WebGL resources. + * + * Use this method when you are done using the map and wish to ensure that it no + * longer consumes browser resources. Afterwards, you must not call any other + * methods on the map. + */ + remove() { + if (this._frameRequest) { + this._frameRequest.abort(); + this._frameRequest = null; + } + this._renderTaskQueue.clear(); + this.handlers.destroy(); + delete this.handlers; + + this._resizeObserver?.disconnect(); + DOM.remove(this._canvasContainer); + this._container.classList.remove('l7-map'); + + this._removed = true; + this.fire(new Event('remove')); + } + + /** + * Trigger the rendering of a single frame. Use this method with custom layers to + * repaint the map when the layer changes. Calling this multiple times before the + * next frame is rendered will still result in only a single frame being rendered. + * @example + * ```ts + * map.triggerRepaint(); + * ``` + */ + triggerRepaint() { + if (!this._frameRequest) { + this._frameRequest = new AbortController(); + browser + .frameAsync(this._frameRequest) + .then((paintStartTimeStamp: number) => { + this._frameRequest = null; + this._render(paintStartTimeStamp); + }) + .catch(() => {}); // ignore abort error + } + } + + /** + * Returns the elevation for the point where the camera is looking. + * This value corresponds to: + * "meters above sea level" * "exaggeration" + * @returns The elevation. + */ + getCameraTargetElevation(): number { + return this.transform.elevation; + } +} diff --git a/packages/map/src/map/util/abort_error.ts b/packages/map/src/map/util/abort_error.ts new file mode 100644 index 00000000000..a635b63d677 --- /dev/null +++ b/packages/map/src/map/util/abort_error.ts @@ -0,0 +1,21 @@ +/** + * An error message to use when an operation is aborted + */ +export const ABORT_ERROR = 'AbortError'; + +/** + * Check if an error is an abort error + * @param error - An error object + * @returns - true if the error is an abort error + */ +export function isAbortError(error: Error): boolean { + return error.message === ABORT_ERROR; +} + +/** + * Use this when you need to create an abort error. + * @returns An error object with the message "AbortError" + */ +export function createAbortError(): Error { + return new Error(ABORT_ERROR); +} diff --git a/packages/map/src/map/util/browser.ts b/packages/map/src/map/util/browser.ts new file mode 100755 index 00000000000..4989f3c05d8 --- /dev/null +++ b/packages/map/src/map/util/browser.ts @@ -0,0 +1,37 @@ +import { createAbortError } from './abort_error'; + +const now = + typeof performance !== 'undefined' && performance && performance.now + ? performance.now.bind(performance) + : Date.now.bind(Date); + +let reducedMotionQuery: MediaQueryList; + +/** */ +export const browser = { + /** + * Provides a function that outputs milliseconds: either performance.now() + * or a fallback to Date.now() + */ + now, + + frameAsync(abortController: AbortController): Promise { + return new Promise((resolve, reject) => { + const frame = requestAnimationFrame(resolve); + abortController.signal.addEventListener('abort', () => { + cancelAnimationFrame(frame); + reject(createAbortError()); + }); + }); + }, + + get prefersReducedMotion(): boolean { + // In case your test crashes when checking matchMedia, call setMatchMedia from 'src/util/test/util' + if (!window.matchMedia) return false; + //Lazily initialize media query + if (reducedMotionQuery == null) { + reducedMotionQuery = window.matchMedia('(prefers-reduced-motion: reduce)'); + } + return reducedMotionQuery.matches; + }, +}; diff --git a/packages/map/src/map/util/dom.ts b/packages/map/src/map/util/dom.ts new file mode 100644 index 00000000000..89f14983484 --- /dev/null +++ b/packages/map/src/map/util/dom.ts @@ -0,0 +1,155 @@ +import Point from '@mapbox/point-geometry'; + +type ScaleReturnValue = { + x: number; + y: number; + boundingClientRect: DOMRect; +}; + +export class DOM { + private static readonly docStyle = + typeof window !== 'undefined' && window.document && window.document.documentElement.style; + + private static userSelect: string; + + private static selectProp = DOM.testProp([ + 'userSelect', + 'MozUserSelect', + 'WebkitUserSelect', + 'msUserSelect', + ]); + + private static transformProp = DOM.testProp(['transform', 'WebkitTransform']); + + private static testProp(props: string[]): string { + if (!DOM.docStyle) return props[0]; + for (let i = 0; i < props.length; i++) { + if (props[i] in DOM.docStyle) { + return props[i]; + } + } + return props[0]; + } + + public static create( + tagName: K, + className?: string, + container?: HTMLElement, + ): HTMLElementTagNameMap[K] { + const el = window.document.createElement(tagName); + if (className !== undefined) el.className = className; + if (container) container.appendChild(el); + return el; + } + + public static createNS(namespaceURI: string, tagName: string) { + const el = window.document.createElementNS(namespaceURI, tagName); + return el; + } + + public static disableDrag() { + if (DOM.docStyle && DOM.selectProp) { + DOM.userSelect = DOM.docStyle[DOM.selectProp]; + DOM.docStyle[DOM.selectProp] = 'none'; + } + } + + public static enableDrag() { + if (DOM.docStyle && DOM.selectProp) { + DOM.docStyle[DOM.selectProp] = DOM.userSelect; + } + } + + public static setTransform(el: HTMLElement, value: string) { + el.style[DOM.transformProp] = value; + } + + public static addEventListener( + target: HTMLElement | Window | Document, + type: string, + callback: EventListenerOrEventListenerObject, + options: { + passive?: boolean; + capture?: boolean; + } = {}, + ) { + if ('passive' in options) { + target.addEventListener(type, callback, options); + } else { + target.addEventListener(type, callback, options.capture); + } + } + + public static removeEventListener( + target: HTMLElement | Window | Document, + type: string, + callback: EventListenerOrEventListenerObject, + options: { + passive?: boolean; + capture?: boolean; + } = {}, + ) { + if ('passive' in options) { + target.removeEventListener(type, callback, options); + } else { + target.removeEventListener(type, callback, options.capture); + } + } + + // Suppress the next click, but only if it's immediate. + private static suppressClickInternal(e) { + e.preventDefault(); + e.stopPropagation(); + window.removeEventListener('click', DOM.suppressClickInternal, true); + } + + public static suppressClick() { + window.addEventListener('click', DOM.suppressClickInternal, true); + window.setTimeout(() => { + window.removeEventListener('click', DOM.suppressClickInternal, true); + }, 0); + } + + private static getScale(element: HTMLElement): ScaleReturnValue { + const rect = element.getBoundingClientRect(); + return { + x: rect.width / element.offsetWidth || 1, + y: rect.height / element.offsetHeight || 1, + boundingClientRect: rect, + }; + } + + private static getPoint(el: HTMLElement, scale: ScaleReturnValue, e: MouseEvent | Touch): Point { + const rect = scale.boundingClientRect; + return new Point( + // rect.left/top values are in page scale (like clientX/Y), + // whereas clientLeft/Top (border width) values are the original values (before CSS scale applies). + (e.clientX - rect.left) / scale.x - el.clientLeft, + (e.clientY - rect.top) / scale.y - el.clientTop, + ); + } + + public static mousePos(el: HTMLElement, e: MouseEvent | Touch): Point { + const scale = DOM.getScale(el); + return DOM.getPoint(el, scale, e); + } + + public static touchPos(el: HTMLElement, touches: TouchList) { + const points: Point[] = []; + const scale = DOM.getScale(el); + for (let i = 0; i < touches.length; i++) { + points.push(DOM.getPoint(el, scale, touches[i])); + } + return points; + } + + public static mouseButton(e: MouseEvent) { + return e.button; + } + + public static remove(node: HTMLElement) { + if (node.parentNode) { + node.parentNode.removeChild(node); + } + } +} diff --git a/packages/map/src/map/util/evented.ts b/packages/map/src/map/util/evented.ts new file mode 100644 index 00000000000..efdcf59f0e6 --- /dev/null +++ b/packages/map/src/map/util/evented.ts @@ -0,0 +1,192 @@ +import { extend } from './util'; + +/** + * A listener method used as a callback to events + */ +export type Listener = (a: any) => any; + +type Listeners = { [_: string]: Array }; + +function _addEventListener(type: string, listener: Listener, listenerList: Listeners) { + const listenerExists = listenerList[type] && listenerList[type].indexOf(listener) !== -1; + if (!listenerExists) { + listenerList[type] = listenerList[type] || []; + listenerList[type].push(listener); + } +} + +function _removeEventListener(type: string, listener: Listener, listenerList: Listeners) { + if (listenerList && listenerList[type]) { + const index = listenerList[type].indexOf(listener); + if (index !== -1) { + listenerList[type].splice(index, 1); + } + } +} + +/** + * The event class + */ +export class Event { + public readonly type: string; + constructor(type: string, data: any = {}) { + extend(this, data); + this.type = type; + } +} + +interface ErrorLike { + message: string; +} + +/** + * An error event + */ +export class ErrorEvent extends Event { + error: ErrorLike; + + constructor(error: ErrorLike, data: any = {}) { + super('error', data); + this.error = error; + } +} + +/** + * Methods mixed in to other classes for event capabilities. + * + * @group Event Related + */ +export class Evented { + _listeners: Listeners; + _oneTimeListeners: Listeners; + _eventedParent: Evented; + _eventedParentData: any | (() => any); + + /** + * Adds a listener to a specified event type. + * + * @param type - The event type to add a listen for. + * @param listener - The function to be called when the event is fired. + * The listener function is called with the data object passed to `fire`, + * extended with `target` and `type` properties. + */ + on(type: string, listener: Listener): this { + this._listeners = this._listeners || {}; + _addEventListener(type, listener, this._listeners); + + return this; + } + + /** + * Removes a previously registered event listener. + * + * @param type - The event type to remove listeners for. + * @param listener - The listener function to remove. + */ + off(type: string, listener: Listener) { + _removeEventListener(type, listener, this._listeners); + _removeEventListener(type, listener, this._oneTimeListeners); + + return this; + } + + /** + * Adds a listener that will be called only once to a specified event type. + * + * The listener will be called first time the event fires after the listener is registered. + * + * @param type - The event type to listen for. + * @param listener - The function to be called when the event is fired the first time. + * @returns `this` or a promise if a listener is not provided + */ + once(type: string, listener?: Listener): this | Promise { + if (!listener) { + return new Promise((resolve) => this.once(type, resolve)); + } + this._oneTimeListeners = this._oneTimeListeners || {}; + _addEventListener(type, listener, this._oneTimeListeners); + + return this; + } + + fire(event: Event | string, properties?: any) { + // Compatibility with (type: string, properties: Object) signature from previous versions. + // See https://github.com/mapbox/mapbox-gl-js/issues/6522, + // https://github.com/mapbox/mapbox-gl-draw/issues/766 + if (typeof event === 'string') { + event = new Event(event, properties || {}); + } + + const type = event.type; + + if (this.listens(type)) { + (event as any).target = this; + + // make sure adding or removing listeners inside other listeners won't cause an infinite loop + const listeners = + this._listeners && this._listeners[type] ? this._listeners[type].slice() : []; + for (const listener of listeners) { + listener.call(this, event); + } + + const oneTimeListeners = + this._oneTimeListeners && this._oneTimeListeners[type] + ? this._oneTimeListeners[type].slice() + : []; + for (const listener of oneTimeListeners) { + _removeEventListener(type, listener, this._oneTimeListeners); + listener.call(this, event); + } + + const parent = this._eventedParent; + if (parent) { + extend( + event, + typeof this._eventedParentData === 'function' + ? this._eventedParentData() + : this._eventedParentData, + ); + parent.fire(event); + } + + // To ensure that no error events are dropped, print them to the + // console if they have no listeners. + } else if (event instanceof ErrorEvent) { + console.error(event.error); + } + + return this; + } + + emit(event: Event | string, properties?: any) { + return this.fire(event, properties); + } + + /** + * Returns a true if this instance of Evented or any forwardeed instances of Evented have a listener for the specified type. + * + * @param type - The event type + * @returns `true` if there is at least one registered listener for specified event type, `false` otherwise + */ + listens(type: string): boolean { + return ( + (this._listeners && this._listeners[type] && this._listeners[type].length > 0) || + (this._oneTimeListeners && + this._oneTimeListeners[type] && + this._oneTimeListeners[type].length > 0) || + (this._eventedParent && this._eventedParent.listens(type)) + ); + } + + /** + * Bubble all events fired by this instance of Evented to this parent instance of Evented. + */ + setEventedParent(parent?: Evented | null, data?: any | (() => any)) { + if (parent) { + this._eventedParent = parent; + } + this._eventedParentData = data; + + return this; + } +} diff --git a/packages/map/src/map/util/task_queue.ts b/packages/map/src/map/util/task_queue.ts new file mode 100644 index 00000000000..9b6d9f4d0ff --- /dev/null +++ b/packages/map/src/map/util/task_queue.ts @@ -0,0 +1,64 @@ +export type TaskID = number; + +type Task = { + callback: (timeStamp: number) => void; + id: TaskID; + cancelled: boolean; +}; + +export class TaskQueue { + _queue: Array; + _id: TaskID; + _cleared: boolean; + _currentlyRunning: Array | false; + + constructor() { + this._queue = []; + this._id = 0; + this._cleared = false; + this._currentlyRunning = false; + } + + add(callback: (timeStamp: number) => void): TaskID { + const id = ++this._id; + const queue = this._queue; + queue.push({ callback, id, cancelled: false }); + return id; + } + + remove(id: TaskID) { + const running = this._currentlyRunning; + const queue = running ? this._queue.concat(running) : this._queue; + for (const task of queue) { + if (task.id === id) { + task.cancelled = true; + return; + } + } + } + + run(timeStamp: number = 0) { + if (this._currentlyRunning) throw new Error('Attempting to run(), but is already running.'); + const queue = (this._currentlyRunning = this._queue); + + // Tasks queued by callbacks in the current queue should be executed + // on the next run, not the current run. + this._queue = []; + + for (const task of queue) { + if (task.cancelled) continue; + task.callback(timeStamp); + if (this._cleared) break; + } + + this._cleared = false; + this._currentlyRunning = false; + } + + clear() { + if (this._currentlyRunning) { + this._cleared = true; + } + this._queue = []; + } +} diff --git a/packages/map/src/map/util/util.ts b/packages/map/src/map/util/util.ts new file mode 100644 index 00000000000..cb0084d7e38 --- /dev/null +++ b/packages/map/src/map/util/util.ts @@ -0,0 +1,171 @@ +import UnitBezier from '@mapbox/unitbezier'; + +export const interpolates = { + number: function number(from: number, to: number, t: number) { + return from + t * (to - from); + }, +}; + +/** + * constrain n to the given range via min + max + * + * @param n - value + * @param min - the minimum value to be returned + * @param max - the maximum value to be returned + * @returns the clamped value + */ +export function clamp(n: number, min: number, max: number): number { + return Math.min(max, Math.max(min, n)); +} + +/** + * constrain n to the given range, excluding the minimum, via modular arithmetic + * + * @param n - value + * @param min - the minimum value to be returned, exclusive + * @param max - the maximum value to be returned, inclusive + * @returns constrained number + */ +export function wrap(n: number, min: number, max: number): number { + const d = max - min; + const w = ((((n - min) % d) + d) % d) + min; + return w === min ? max : w; +} + +let id = 1; + +/** + * Return a unique numeric id, starting at 1 and incrementing with + * each call. + * + * @returns unique numeric id. + */ +export function uniqueId(): number { + return id++; +} + +/** + * Given a destination object and optionally many source objects, + * copy all properties from the source objects into the destination. + * The last source object given overrides properties from previous + * source objects. + * + * @param dest - destination object + * @param sources - sources from which properties are pulled + */ +export function extend(dest: T, source: U): T & U; +export function extend(dest: T, source1: U, source2: V): T & U & V; +export function extend( + dest: T, + source1: U, + source2: V, + source3: W, +): T & U & V & W; +export function extend(dest: Record, ...sources: Array): any; +export function extend(dest: Record, ...sources: Array): any { + for (const src of sources) { + for (const k in src) { + dest[k] = src[k]; + } + } + return dest; +} + +// See https://stackoverflow.com/questions/49401866/all-possible-keys-of-an-union-type +type KeysOfUnion = T extends T ? keyof T : never; + +/** + * Given an object and a number of properties as strings, return version + * of that object with only those properties. + * + * @param src - the object + * @param properties - an array of property names chosen + * to appear on the resulting object. + * @returns object with limited properties. + * @example + * ```ts + * let foo = { name: 'Charlie', age: 10 }; + * let justName = pick(foo, ['name']); // justName = { name: 'Charlie' } + * ``` + */ +export function pick(src: T, properties: Array>): Partial { + const result: Partial = {}; + for (let i = 0; i < properties.length; i++) { + const k = properties[i]; + if (k in src) { + result[k] = src[k]; + } + } + return result; +} + +/** + * Makes optional keys required and add the the undefined type. + * + * ``` + * interface Test { + * foo: number; + * bar?: number; + * baz: number | undefined; + * } + * + * Complete { + * foo: number; + * bar: number | undefined; + * baz: number | undefined; + * } + * + * ``` + * + * See https://medium.com/terria/typescript-transforming-optional-properties-to-required-properties-that-may-be-undefined-7482cb4e1585 + */ + +export type Complete = { + [P in keyof Required]: Pick extends Required> ? T[P] : T[P] | undefined; +}; + +/** + * Given given (x, y), (x1, y1) control points for a bezier curve, + * return a function that interpolates along that curve. + * + * @param p1x - control point 1 x coordinate + * @param p1y - control point 1 y coordinate + * @param p2x - control point 2 x coordinate + * @param p2y - control point 2 y coordinate + */ +export function bezier(p1x: number, p1y: number, p2x: number, p2y: number): (t: number) => number { + const bezier = new UnitBezier(p1x, p1y, p2x, p2y); + return (t: number) => { + return bezier.solve(t); + }; +} + +/** + * A default bezier-curve powered easing function with + * control points (0.25, 0.1) and (0.25, 1) + */ +export const defaultEasing = bezier(0.25, 0.1, 0.25, 1); + +/** + * Print a warning message to the console and ensure duplicate warning messages + * are not printed. + */ +const warnOnceHistory: { [key: string]: boolean } = {}; + +export function warnOnce(message: string): void { + if (!warnOnceHistory[message]) { + // console isn't defined in some WebWorkers, see #2558 + if (typeof console !== 'undefined') console.warn(message); + warnOnceHistory[message] = true; + } +} + +/** + * This method converts degrees to radians. + * The return value is the radian value. + * @param degrees - The number of degrees + * @returns radians + */ +export function degreesToRadians(degrees: number): number { + return (degrees * Math.PI) / 180; +} diff --git a/packages/map/tsconfig.json b/packages/map/tsconfig.json index 4082f16a5d9..c5253f50b74 100644 --- a/packages/map/tsconfig.json +++ b/packages/map/tsconfig.json @@ -1,3 +1,6 @@ { - "extends": "../../tsconfig.json" + "extends": "../../tsconfig.json", + "compilerOptions": { + "strict": false + } } diff --git a/packages/maps/CHANGELOG.md b/packages/maps/CHANGELOG.md index 9c9c0a3e319..25ef3d7e69d 100644 --- a/packages/maps/CHANGELOG.md +++ b/packages/maps/CHANGELOG.md @@ -1,5 +1,81 @@ # Change Log +## 2.21.11-beta.7 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.7 + - @antv/l7-map@2.21.11-beta.7 + - @antv/l7-utils@2.21.11-beta.7 + +## 2.21.11-beta.6 + +### Patch Changes + +- Updated dependencies [[`7e38a83`](https://github.com/antvis/L7/commit/7e38a83d9324fb9443f5a04e6d2fc9a1fef9c17c)]: + - @antv/l7-map@2.21.11-beta.6 + - @antv/l7-core@2.21.11-beta.6 + - @antv/l7-utils@2.21.11-beta.6 + +## 2.21.11-beta.5 + +### Patch Changes + +- [#2518](https://github.com/antvis/L7/pull/2518) [`8939e9b`](https://github.com/antvis/L7/commit/8939e9bc0e744d75b5b469c221d6695c7a313e83) Thanks [@lvisei](https://github.com/lvisei)! - fix: 修复在 Map 上使用组件事件穿透到图层上的问题 + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.5 + - @antv/l7-map@2.21.11-beta.5 + - @antv/l7-utils@2.21.11-beta.5 + +## 2.21.11-beta.4 + +### Patch Changes + +- [#2513](https://github.com/antvis/L7/pull/2513) [`cca16a3`](https://github.com/antvis/L7/commit/cca16a3d72de462afa9d71c386c82f92952d1c47) Thanks [@lvisei](https://github.com/lvisei)! - fix: 天地图 setCenter 方法缺失 + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.4 + - @antv/l7-map@2.21.11-beta.4 + - @antv/l7-utils@2.21.11-beta.4 + +## 2.21.11-beta.3 + +### Patch Changes + +- Updated dependencies [[`a5f57ed`](https://github.com/antvis/L7/commit/a5f57eda52dab160fe076f252ad52cd51b8f456a)]: + - @antv/l7-core@2.21.11-beta.3 + - @antv/l7-map@2.21.11-beta.3 + - @antv/l7-utils@2.21.11-beta.3 + +## 2.21.11-beta.2 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.2 + - @antv/l7-map@2.21.11-beta.2 + - @antv/l7-utils@2.21.11-beta.2 + +## 2.21.11-beta.1 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.1 + - @antv/l7-map@2.21.11-beta.1 + - @antv/l7-utils@2.21.11-beta.1 + +## 2.21.11-beta.0 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.0 + - @antv/l7-map@2.21.11-beta.0 + - @antv/l7-utils@2.21.11-beta.0 + ## 2.21.10 ### Patch Changes diff --git a/packages/maps/__tests__/map.spec.ts b/packages/maps/__tests__/map.spec.ts index f8bb3eda5db..3708593331d 100644 --- a/packages/maps/__tests__/map.spec.ts +++ b/packages/maps/__tests__/map.spec.ts @@ -1,5 +1,5 @@ import { createSceneContainer } from '@antv/l7-core'; -import AMapService from '../src/amap2/map'; +import AMapService from '../src/amap-next/map'; describe('maps', () => { it('AMapService', () => { diff --git a/packages/maps/package.json b/packages/maps/package.json index 78d0fd63d9a..3839434608a 100644 --- a/packages/maps/package.json +++ b/packages/maps/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7-maps", - "version": "2.21.10", + "version": "2.21.11-beta.7", "description": "Maps for L7", "license": "MIT", "author": "https://github.com/orgs/antvis/people", diff --git a/packages/maps/src/amap-next/index.ts b/packages/maps/src/amap-next/index.ts new file mode 100644 index 00000000000..ba35d784fbc --- /dev/null +++ b/packages/maps/src/amap-next/index.ts @@ -0,0 +1,8 @@ +import BaseMapWrapper from '../utils/BaseMapWrapper'; +import MapService from './map'; + +export default class AMap2Wrapper extends BaseMapWrapper { + protected getServiceConstructor() { + return MapService; + } +} diff --git a/packages/maps/src/amap2/logo.css b/packages/maps/src/amap-next/logo.css similarity index 100% rename from packages/maps/src/amap2/logo.css rename to packages/maps/src/amap-next/logo.css diff --git a/packages/maps/src/amap-next/map.ts b/packages/maps/src/amap-next/map.ts new file mode 100644 index 00000000000..826de03a164 --- /dev/null +++ b/packages/maps/src/amap-next/map.ts @@ -0,0 +1,462 @@ +import AMapLoader from '@amap/amap-jsapi-loader'; +import type { + Bounds, + ICameraOptions, + ILngLat, + IMercator, + IPoint, + IStatusOptions, + MapStyleConfig, + MapStyleName, +} from '@antv/l7-core'; +import { MapServiceEvent } from '@antv/l7-core'; +import { DOM, amap2Project, lodashUtil } from '@antv/l7-utils'; +import { mat4, vec3 } from 'gl-matrix'; +import BaseMap from '../lib/base-map'; +import Viewport from '../lib/web-mercator-viewport'; +import { MapType } from '../types'; +import { toPaddingOptions } from '../utils/utils'; +import './logo.css'; +import { MapTheme } from './theme'; + +const AMAP_VERSION = '2.0'; +const AMAP_API_KEY = 'f59bcf249433f8b05caaee19f349b3d7'; +const ZOOM_OFFSET = 1; + +const AMapEventMapV2: Record = { + contextmenu: 'rightclick', + camerachange: 'viewchange', +}; + +export default class BMapService extends BaseMap { + protected viewport = new Viewport(); + + public version = MapType.GAODE; + + public getType() { + return 'amap'; + } + + public async init() { + const { + id, + style = 'light', + minZoom = 0, + maxZoom = 24, + token = AMAP_API_KEY, + mapInstance, + plugin = [], + ...rest + } = this.config; + + if (!(window.AMap || mapInstance)) { + plugin.push('Map3D'); + await AMapLoader.load({ + key: token, // 申请好的Web端开发者Key,首次调用 load 时必填 + version: AMAP_VERSION, // 指定要加载的 JSAPI 的版本 + plugins: plugin, // 需要使用的的插件列表,如比例尺'AMap.Scale'等 + }); + } + + if (mapInstance) { + this.map = mapInstance; + this.mapContainer = this.map.getContainer(); + + this.map.on('viewchange', this.handleCameraChanged); + } else { + const mapConstructorOptions: AMap.Map.Options = { + mapStyle: this.getMapStyleValue(style as string), + // 默认取值范围 [2, 20] + zooms: [minZoom, maxZoom], + viewMode: '3D', + ...rest, + // 地图平移过程中是否使用动画(如调用 panBy、panTo、setCenter、setZoomAndCenter 等函数, 将对地图产生平移操作, 是否使用动画平移的效果), 默认为 true , 即使用动画 + // animateEnable: false, + // 地图使用缓动效果 + // jogEnable: false, + }; + + if (mapConstructorOptions.zoom) { + // 高德地图在相同大小下需要比 MapBox 多一个 zoom 层级 + mapConstructorOptions.zoom += ZOOM_OFFSET; + } + + if (token === AMAP_API_KEY) { + (window as any)._AMapSecurityConfig = { + securityJsCode: '2653011adeb04230b3a26cc9a780a800', + }; + console.warn( + `%c${this.configService.getSceneWarninfo('MapToken')}!`, + 'color: #873bf4;font-weigh:900;font-size: 16px;', + ); + } + + if (!id) { + throw Error('No container id specified'); + } + + // https://lbs.amap.com/faq/other-product/1000080679/1000080682/1060894069 + (window as any).forceWebGL = true; + + this.mapContainer = this.creatMapContainer(id); + + const map = new AMap.Map(this.mapContainer, mapConstructorOptions); + + this.map = map; + + // 监听地图相机事件 + map.on('viewchange', this.handleCameraChanged); + } + + this.syncInitViewPort(); + } + + private syncInitViewPort() { + const option = this.getViewState(); + this.updateView(option); + } + + protected handleCameraChanged = () => { + const option = this.getViewState(); + this.updateView(option); + }; + + private getViewState() { + const { center, zoom } = getMapHighPrecisionState(this.map); + const option = { + center: center, + viewportWidth: this.map.getContainer()!.clientWidth, + viewportHeight: this.map.getContainer()!.clientHeight, + bearing: -this.map.getRotation(), + pitch: this.map.getPitch(), + zoom: zoom - ZOOM_OFFSET, + }; + + return option; + } + + protected creatMapContainer(id: string | HTMLDivElement) { + const wrapper = super.creatMapContainer(id); + const amapdiv = document.createElement('div'); + amapdiv.style.cssText += ` + position: absolute; + top: 0; + height: 100%; + width: 100%; + `; + amapdiv.id = lodashUtil.uniqueId('l7_amap_div'); + wrapper.appendChild(amapdiv); + return amapdiv; + } + + public getContainer(): HTMLElement | null { + return this.map.getContainer(); + } + + public addMarkerContainer(): void { + if (!this.map) return; + + const mapContainer = this.map.getContainer(); + if (mapContainer !== null) { + const amap = mapContainer.getElementsByClassName('amap-maps')[0] as HTMLElement; + // amap2 的 amap-maps 新增 z-index=0; 样式,让 marker 中 zIndex 失效 + amap.style.zIndex = 'auto'; + this.markerContainer = DOM.create('div', 'l7-marker-container2', amap); + } + } + + public getMarkerContainer(): HTMLElement { + return this.markerContainer; + } + + public getCanvasOverlays() { + return this.mapContainer?.querySelector('.amap-overlays') as HTMLElement; + } + + // MapEvent // 定义事件类型 + public on(type: string, handler: (...args: any[]) => void): void { + if (MapServiceEvent.indexOf(type) !== -1) { + this.eventEmitter.on(type, handler); + } else { + this.map.on(AMapEventMapV2[type] || type, handler); + } + } + + public off(type: string, handler: (...args: any[]) => void): void { + if (MapServiceEvent.indexOf(type) !== -1) { + this.eventEmitter.off(type, handler); + } else { + this.map.off(AMapEventMapV2[type] || type, handler); + } + } + + public getSize(): [number, number] { + const size = this.map.getSize(); + return [size.getWidth(), size.getHeight()]; + } + + public getMinZoom(): number { + // @ts-ignore + const zooms: [number, number] = this.map.getZooms(); + return zooms[0] - ZOOM_OFFSET; + } + public getMaxZoom(): number { + // @ts-ignore + const zooms: [number, number] = this.map.getZooms(); + return zooms[1] - ZOOM_OFFSET; + } + + public getZoom(): number { + // 统一返回 Mapbox 缩放等级 + return this.map.getZoom() - ZOOM_OFFSET; + } + + public getCenter(options?: ICameraOptions): ILngLat { + if (options?.padding) { + const originCenter = this.getCenter(); + const padding = toPaddingOptions(options.padding); + const px = this.lngLatToPixel([originCenter.lng, originCenter.lat]); + const offsetPx = [(padding.right - padding.left) / 2, (padding.bottom - padding.top) / 2]; + + const newCenter = this.pixelToLngLat([px.x - offsetPx[0], px.y - offsetPx[1]]); + return newCenter; + } + const center = this.map.getCenter(); + return { + lng: center.getLng(), + lat: center.getLat(), + }; + } + + public getPitch(): number { + return this.map.getPitch(); + } + + public getRotation(): number { + // 统一返回逆时针旋转角度 + return 360 - this.map.getRotation(); + } + + public getBounds(): Bounds { + const bounds = this.map.getBounds(); + const NE = bounds.getNorthEast(); + const SW = bounds.getSouthWest(); + const center = this.getCenter(); + const maxlng = + center.lng > NE.getLng() || center.lng < SW.getLng() ? 180 - NE.getLng() : NE.getLng(); + const minlng = center.lng < SW.getLng() ? SW.getLng() - 180 : SW.getLng(); + // 兼容 Mapbox,统一返回西南、东北 + return [ + [minlng, SW.getLat()], + [maxlng, NE.getLat()], + ]; + } + + public getMapContainer() { + return this.mapContainer; + } + + public getMapCanvasContainer(): HTMLElement { + return this.map.getContainer()?.getElementsByClassName('amap-maps')[0] as HTMLElement; + } + + public getMapStyleConfig(): MapStyleConfig { + return MapTheme; + } + + public getMapStyleValue(name: string) { + return this.getMapStyleConfig()[name] || name; + } + + public getMapStyle(): string { + return this.map.getMapStyle(); + } + + public setMapStyle(style: MapStyleName): void { + this.map.setMapStyle(this.getMapStyleValue(style)); + } + + public setRotation(rotation: number): void { + return this.map.setRotation(rotation); + } + + public zoomIn(): void { + this.map.zoomIn(); + } + + public zoomOut(): void { + this.map.zoomOut(); + } + + public panTo(p: [number, number]): void { + this.map.panTo(p); + } + + public panBy(x: number = 0, y: number = 0): void { + this.map.panBy(x, y); + } + + public fitBounds(extent: Bounds): void { + this.map.setBounds( + new AMap.Bounds([extent[0][0], extent[0][1], extent[1][0], extent[1][1]]), + // @ts-expect-error 立即缩放到指定位置 + true, + ); + } + + public setZoomAndCenter(zoom: number, center: [number, number]): void { + this.map.setZoomAndCenter(zoom + ZOOM_OFFSET, center); + } + + public setCenter(lnglat: [number, number], options?: ICameraOptions): void { + if (options?.padding) { + const padding = toPaddingOptions(options.padding); + const px = this.lngLatToPixel(lnglat); + const offsetPx = [(padding.right - padding.left) / 2, (padding.bottom - padding.top) / 2]; + const newCenter = this.pixelToLngLat([px.x + offsetPx[0], px.y + offsetPx[1]]); + this.map.setCenter([newCenter.lng, newCenter.lat]); + } else { + this.map.setCenter(lnglat); + } + } + + public setPitch(pitch: number) { + return this.map.setPitch(pitch); + } + + public setZoom(zoom: number): void { + // 统一设置 Mapbox 缩放等级 + return this.map.setZoom(zoom + ZOOM_OFFSET); + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public setMaxZoom(max: number): void { + throw new Error('Method not implemented.'); + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public setMinZoom(min: number): void { + throw new Error('Method not implemented.'); + } + + public setMapStatus(option: Partial): void { + this.map.setStatus(option); + } + + public meterToCoord(center: [number, number], outer: [number, number]) { + // Tip: 实际米距离 unit meter + const meterDis = AMap.GeometryUtil.distance( + new AMap.LngLat(...center), + new AMap.LngLat(...outer), + ); + + // Tip: 三维世界坐标距离 + const [x1, y1] = amap2Project(...center); + const [x2, y2] = amap2Project(...outer); + const coordDis = Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)); + + return coordDis / meterDis; + } + + public pixelToLngLat(pixel: [number, number]): ILngLat { + const lngLat = this.map.pixelToLngLat(new AMap.Pixel(pixel[0], pixel[1])); + return { lng: lngLat.getLng(), lat: lngLat.getLat() }; + } + + public lngLatToPixel(lnglat: [number, number]): IPoint { + const p = this.map.lnglatToPixel(lnglat); + return { + x: p.getX(), + y: p.getY(), + }; + } + + public containerToLngLat(pixel: [number, number]): ILngLat { + const ll = new AMap.Pixel(pixel[0], pixel[1]); + const lngLat = this.map.containerToLngLat(ll); + return { + lng: lngLat?.getLng(), + lat: lngLat?.getLat(), + }; + } + + public lngLatToContainer(lnglat: [number, number]): IPoint { + const pixel = this.map.lngLatToContainer(lnglat); + return { + x: pixel.getX(), + y: pixel.getY(), + }; + } + + /** + * 将经纬度转成墨卡托坐标 + */ + public lngLatToMercator([lng, lat]: [number, number], altitude: number): IMercator { + const [x, y] = amap2Project(lng, lat); + return { + x: x, + y: y, + z: altitude, + }; + } + + public getModelMatrix( + lnglat: [number, number], + altitude: number, + rotate: [number, number, number], + scale: [number, number, number] = [1, 1, 1], + ): number[] { + const flat = this.viewport.projectFlat(lnglat); + const modelMatrix = mat4.create(); + + mat4.translate(modelMatrix, modelMatrix, vec3.fromValues(flat[0], flat[1], altitude)); + mat4.scale(modelMatrix, modelMatrix, vec3.fromValues(scale[0], scale[1], scale[2])); + + mat4.rotateX(modelMatrix, modelMatrix, rotate[0]); + mat4.rotateY(modelMatrix, modelMatrix, rotate[1]); + mat4.rotateZ(modelMatrix, modelMatrix, rotate[2]); + + return modelMatrix as unknown as number[]; + } + + public exportMap(type: 'jpg' | 'png'): string { + const renderCanvas = this.getContainer()?.getElementsByClassName( + 'amap-layer', + )[0] as HTMLCanvasElement; + const layersPng = + type === 'jpg' + ? (renderCanvas?.toDataURL('image/jpeg') as string) + : (renderCanvas?.toDataURL('image/png') as string); + return layersPng; + } + + public destroy(): void { + super.destroy(); + // 销毁地图可视化层的容器 + this.mapContainer?.parentNode?.removeChild(this.mapContainer); + + // @ts-ignore + delete window.initAMap; + + const $jsapi = document.getElementById('amap-script'); + if ($jsapi) { + document.head.removeChild($jsapi); + } + this.map.destroy(); + } +} + +/** + * 访问高精度的地图状态(临时解决方案) + * - 解决 map.getCenter() 方法只返回小数点五位有效数据 + * - 解决 map.getZoom() 方法只返回小数点两位有效数据 + */ +function getMapHighPrecisionState(map: AMap.Map) { + // @ts-expect-error 访问未暴露的内部属性 + const viewStatus = map._view.getOptions(); + + const center: [number, number] = viewStatus.center; + const zoom: number = viewStatus.zoom; + + return { center, zoom }; +} diff --git a/packages/maps/src/utils/amap/theme.ts b/packages/maps/src/amap-next/theme.ts similarity index 100% rename from packages/maps/src/utils/amap/theme.ts rename to packages/maps/src/amap-next/theme.ts diff --git a/packages/maps/src/amap/Viewport.ts b/packages/maps/src/amap/Viewport.ts deleted file mode 100644 index d50a577c7da..00000000000 --- a/packages/maps/src/amap/Viewport.ts +++ /dev/null @@ -1,127 +0,0 @@ -import type { IMapCamera, IViewport } from '@antv/l7-core'; -import { mat4, vec3 } from 'gl-matrix'; - -const DEGREES_TO_RADIANS = Math.PI / 180; - -export default class Viewport implements IViewport { - private projectionMatrix: mat4 = mat4.create(); - private viewMatrix: mat4 = mat4.create(); - private viewProjectionMatrix: mat4 = mat4.create(); - private ViewProjectionMatrixUncentered: mat4 = mat4.create(); - private viewUncenteredMatrix: mat4 = mat4.create(); - private zoom: number; - private center: number[]; - - public syncWithMapCamera(mapCamera: Partial) { - const { - zoom = 1, - pitch = 0, - bearing = 0, - center = [0, 0], - offsetOrigin = [0, 0], - cameraHeight = 1, - aspect = 1, - near = 0.1, - far = 1000, - fov = 0, - } = mapCamera; - this.zoom = zoom; - this.center = center; - - const pitchInRadians = pitch * DEGREES_TO_RADIANS; - const rotationInRadians = (360 - bearing) * DEGREES_TO_RADIANS; - - // 计算透视投影矩阵 projectionMatrix - mat4.perspective(this.projectionMatrix, fov, aspect, near, far); - // 计算相机矩阵 viewMatrix - const eye = vec3.fromValues( - cameraHeight * Math.sin(pitchInRadians) * Math.sin(rotationInRadians), - -cameraHeight * Math.sin(pitchInRadians) * Math.cos(rotationInRadians), - cameraHeight * Math.cos(pitchInRadians), - ); - const up = vec3.fromValues( - -Math.cos(pitchInRadians) * Math.sin(rotationInRadians), - Math.cos(pitchInRadians) * Math.cos(rotationInRadians), - Math.sin(pitchInRadians), - ); - mat4.lookAt(this.viewMatrix, eye, vec3.fromValues(0, 0, 0), up); - this.viewUncenteredMatrix = mat4.clone(this.viewMatrix); - - // 移动相机位置 - mat4.translate( - this.viewMatrix, - this.viewMatrix, - vec3.fromValues(-offsetOrigin[0], offsetOrigin[1], 0), - ); - - mat4.multiply(this.viewProjectionMatrix, this.projectionMatrix, this.viewMatrix); - mat4.multiply(this.ViewProjectionMatrixUncentered, this.projectionMatrix, this.viewMatrix); - } - - public getZoom(): number { - return this.zoom; - } - - public getZoomScale(): number { - // 512 尺寸下的缩放:2 ^ 19 - return 524288; - } - - public getCenter(): [number, number] { - const [lng, lat] = this.center; - return [lng, lat]; - } - - public getProjectionMatrix(): number[] { - // @ts-ignore - return this.projectionMatrix; - } - - public getModelMatrix(): number[] { - return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; - } - - public getViewMatrix(): number[] { - // @ts-ignore - return this.viewMatrix; - } - - public getViewMatrixUncentered(): number[] { - // @ts-ignore - return this.viewUncenteredMatrix; - } - public getViewProjectionMatrix(): number[] { - // @ts-ignore - return this.viewProjectionMatrix; - } - - public getViewProjectionMatrixUncentered(): number[] { - // @ts-ignore - return this.ViewProjectionMatrixUncentered; - } - - public getFocalDistance() { - return 1; - } - - /** - * P20 坐标系,固定 scale - */ - public projectFlat(lngLat: [number, number]): [number, number] { - const maxs = 85.0511287798; - const lat = Math.max(Math.min(maxs, lngLat[1]), -maxs); - // tslint:disable-next-line:no-bitwise - const zoomScale = 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; - const b = 0.5; - const c = -0.5 / Math.PI; - d = 0.5; - x = zoomScale * (a * x + b) - 215440491; - y = -(zoomScale * (c * y + d) - 106744817); - return [x, y]; - } -} diff --git a/packages/maps/src/amap/index.ts b/packages/maps/src/amap/index.ts deleted file mode 100644 index 25a60c9b83f..00000000000 --- a/packages/maps/src/amap/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { IAMapInstance } from '../types'; -import BaseMapWrapper from '../utils/BaseMapWrapper'; -import AMapService from './map'; - -export default class AMapWrapper extends BaseMapWrapper { - protected getServiceConstructor() { - return AMapService; - } -} diff --git a/packages/maps/src/amap/logo.css b/packages/maps/src/amap/logo.css deleted file mode 100644 index 1aeba6db389..00000000000 --- a/packages/maps/src/amap/logo.css +++ /dev/null @@ -1,6 +0,0 @@ -.amap-logo { - display: none !important; -} -.amap-overlays { - z-index: 3 !important; -} diff --git a/packages/maps/src/amap/map.ts b/packages/maps/src/amap/map.ts deleted file mode 100644 index 337c416de6b..00000000000 --- a/packages/maps/src/amap/map.ts +++ /dev/null @@ -1,213 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -/** - * AMapService - */ -import type { IMapCamera, IMapService, IViewport } from '@antv/l7-core'; -import { CoordinateSystem } from '@antv/l7-core'; -import { mat4, vec3 } from 'gl-matrix'; -import type { IAMapEvent, IAMapInstance } from '../types'; -import AMapBaseService from '../utils/amap/AMapBaseService'; -import AMapLoader from '../utils/amaploader'; -import Viewport from './Viewport'; -// @ts-ignore -window.forceWebGL = true; - -const AMAP_API_KEY: string = '15cd8a57710d40c9b7c0e3cc120f1200'; -const AMAP_VERSION: string = '1.4.15'; - -/** - * 高德地图脚本是否加载完毕 - */ -let amapLoaded = false; -/** - * 高德地图脚本加载成功等待队列,成功之后依次触发 - */ -let pendingResolveQueue: Array<() => void> = []; -const LNGLAT_OFFSET_ZOOM_THRESHOLD = 12; // 暂时关闭 fix 统一不同坐标系,不同底图的高度位置 - -/** - * AMapService - */ -export default class AMapService - extends AMapBaseService - implements IMapService -{ - public version: string = 'GAODE1.x'; - protected viewport: IViewport; - - public getModelMatrix( - lnglat: [number, number], - altitude: number, - rotate: [number, number, number], - scale: [number, number, number] = [1, 1, 1], - ): number[] { - const flat = this.viewport.projectFlat(lnglat); - // @ts-ignore - const modelMatrix = mat4.create(); - - mat4.translate(modelMatrix, modelMatrix, vec3.fromValues(flat[0], flat[1], altitude)); - mat4.scale(modelMatrix, modelMatrix, vec3.fromValues(scale[0], scale[1], scale[2])); - - mat4.rotateX(modelMatrix, modelMatrix, rotate[0]); - mat4.rotateY(modelMatrix, modelMatrix, rotate[1]); - mat4.rotateZ(modelMatrix, modelMatrix, rotate[2]); - - return modelMatrix as unknown as number[]; - } - - public async init(): Promise { - const { - id, - style = 'light', - minZoom = 0, - maxZoom = 18, - token = AMAP_API_KEY, - mapInstance, - plugin = [], - ...rest - } = this.config; - // 高德地图创建独立的container; - // tslint:disable-next-line:typedef - await new Promise((resolve) => { - const resolveMap = () => { - if (mapInstance) { - this.map = mapInstance as AMap.Map & IAMapInstance; - this.$mapContainer = this.map.getContainer(); - setTimeout(() => { - this.map.on('camerachange', this.handleCameraChanged); - resolve(); - }, 30); - } else { - this.$mapContainer = this.creatMapContainer(id as string | HTMLDivElement); - const mapConstructorOptions = { - mapStyle: this.getMapStyleValue(style as string), - zooms: [minZoom, maxZoom], - viewMode: '3D', - ...rest, - }; - if (mapConstructorOptions.zoom) { - // 高德地图在相同大小下需要比 MapBox 多一个 zoom 层级 - mapConstructorOptions.zoom += 1; - } - // @ts-ignore - const map = new AMap.Map(this.$mapContainer, mapConstructorOptions); - // 监听地图相机事件 - map.on('camerachange', this.handleCameraChanged); - // Tip: 为了兼容开启 MultiPassRender 的情况 - // 修复 MultiPassRender 在高德地图 1.x 的情况下,缩放地图改变 zoom 时存在可视化层和底图不同步的现象 - map.on('camerachange', () => { - setTimeout(() => this.handleAfterMapChange()); - }); - - // @ts-ignore - this.map = map; - setTimeout(() => { - resolve(); - }, 10); - } - }; - if (!amapLoaded && !mapInstance) { - if (token === AMAP_API_KEY) { - console.warn(this.configService.getSceneWarninfo('MapToken')); - } - amapLoaded = true; - plugin.push('Map3D'); - AMapLoader.load({ - key: token, // 申请好的Web端开发者Key,首次调用 load 时必填 - version: AMAP_VERSION, // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15 - plugins: plugin, // 需要使用的的插件列表,如比例尺'AMap.Scale'等 - }) - .then((AMap) => { - resolveMap(); - - if (pendingResolveQueue.length) { - pendingResolveQueue.forEach((r) => r()); - pendingResolveQueue = []; - } - }) - .catch((e) => { - throw new Error(e); - }); - } else { - if ((amapLoaded && window.AMap) || mapInstance) { - resolveMap(); - } else { - pendingResolveQueue.push(resolveMap); - } - } - }); - - this.viewport = new Viewport(); - } - - public meterToCoord(center: [number, number], outer: [number, number]) { - // 统一根据经纬度来转化 - // Tip: 实际米距离 unit meter - const meterDis = AMap.GeometryUtil.distance( - new AMap.LngLat(...center), - new AMap.LngLat(...outer), - ); - - // Tip: 三维世界坐标距离 - const [x1, y1] = this.lngLatToCoord(center); - const [x2, y2] = this.lngLatToCoord(outer); - const coordDis = Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)); - - return coordDis / meterDis; - } - - // tslint:disable-next-line:no-empty - public updateView(viewOption: Partial): void {} - - public getOverlayContainer(): HTMLElement | undefined { - return undefined; - } - - public exportMap(type: 'jpg' | 'png'): string { - const renderCanvas = this.getContainer()?.getElementsByClassName( - 'amap-layer', - )[0] as HTMLCanvasElement; - const layersPng = - type === 'jpg' - ? (renderCanvas?.toDataURL('image/jpeg') as string) - : (renderCanvas?.toDataURL('image/png') as string); - return layersPng; - } - - public onCameraChanged(callback: (viewport: IViewport) => void): void { - this.cameraChangedCallback = callback; - } - - protected handleCameraChanged = (e: IAMapEvent): void => { - const { fov, near, far, height, pitch, rotation, aspect, position } = e.camera; - const { lng, lat } = this.getCenter(); - // Tip: 触发地图变化事件 - this.emit('mapchange'); - - if (this.cameraChangedCallback) { - this.viewport.syncWithMapCamera({ - aspect, - // AMap 定义 rotation 为顺时针方向,而 Mapbox 为逆时针 - // @see https://docs.mapbox.com/mapbox-gl-js/api/#map#getbearing - bearing: 360 - rotation, - far, - fov, - cameraHeight: height, - near, - pitch, - // AMap 定义的缩放等级 与 Mapbox 相差 1 - zoom: this.map.getZoom() - 1, - center: [lng, lat], - offsetOrigin: [position.x, position.y], - }); - const { offsetZoom = LNGLAT_OFFSET_ZOOM_THRESHOLD } = this.config; - // set coordinate system - if (this.viewport.getZoom() > offsetZoom) { - this.coordinateSystemService.setCoordinateSystem(CoordinateSystem.P20_OFFSET); - } else { - this.coordinateSystemService.setCoordinateSystem(CoordinateSystem.P20); - } - this.cameraChangedCallback(this.viewport); - } - }; -} diff --git a/packages/maps/src/amap2/Viewport.ts b/packages/maps/src/amap2/Viewport.ts deleted file mode 100644 index ca7358e5f06..00000000000 --- a/packages/maps/src/amap2/Viewport.ts +++ /dev/null @@ -1,120 +0,0 @@ -import type { IMapCamera, IViewport } from '@antv/l7-core'; -import { mat4, vec3 } from 'gl-matrix'; -export default class Viewport implements IViewport { - private projectionMatrix: mat4 = mat4.create(); - private viewMatrix: mat4 = mat4.create(); - private viewProjectionMatrix: mat4 = mat4.create(); - private ViewProjectionMatrixUncentered: mat4 = mat4.create(); - private viewUncenteredMatrix: mat4 = mat4.create(); - private zoom: number; - private center: number[]; - - public syncWithMapCamera(mapCamera: Partial) { - const { - zoom = 1, - center = [0, 0], - offsetOrigin = [0, 0], - cameraPosition = [0, 0, 0], - up = [0, 1, 0], - lookAt = [0, 0, 0], - aspect = 1, - near = 0.1, - far = 1000, - fov = 45, - // @ts-ignore - // left, - // right, - // bottom, - // top, - } = mapCamera; - this.zoom = zoom; - this.center = center; - - // 计算透视投影矩阵 projectionMatrix - mat4.perspective(this.projectionMatrix, (fov / 180) * Math.PI, aspect, near, far); - - const eyePoint = vec3.fromValues(...cameraPosition); - const lookAtPoint = vec3.fromValues(...lookAt); - const upDirect = vec3.fromValues(...up); - mat4.lookAt(this.viewMatrix, eyePoint, lookAtPoint, upDirect); - - this.viewUncenteredMatrix = mat4.clone(this.viewMatrix); - - // 移动相机位置 - mat4.translate( - this.viewMatrix, - this.viewMatrix, - vec3.fromValues(-offsetOrigin[0], offsetOrigin[1], 0), - ); - - mat4.multiply(this.viewProjectionMatrix, this.projectionMatrix, this.viewMatrix); - mat4.multiply(this.ViewProjectionMatrixUncentered, this.projectionMatrix, this.viewMatrix); - } - - public getZoom(): number { - return this.zoom; - } - - public getZoomScale(): number { - // 512 尺寸下的缩放:2 ^ 20 - return 1048576; - } - - public getCenter(): [number, number] { - const [lng, lat] = this.center; - return [lng, lat]; - } - - public getProjectionMatrix(): number[] { - // @ts-ignore - return this.projectionMatrix; - } - - public getModelMatrix(): number[] { - return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; - } - - public getViewMatrix(): number[] { - // @ts-ignore - return this.viewMatrix; - } - - public getViewMatrixUncentered(): number[] { - // @ts-ignore - return this.viewUncenteredMatrix; - } - public getViewProjectionMatrix(): number[] { - // @ts-ignore - return this.viewProjectionMatrix; - } - - public getViewProjectionMatrixUncentered(): number[] { - // @ts-ignore - return this.ViewProjectionMatrixUncentered; - } - - public getFocalDistance() { - return 1.2; - } - - /** - * P20 坐标系,固定 scale - */ - public projectFlat(lngLat: [number, number]): [number, number] { - const maxs = 85.0511287798; - const lat = Math.max(Math.min(maxs, lngLat[1]), -maxs); - // tslint:disable-next-line:no-bitwise - const zoomScale = 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; - const b = 0.5; - const c = -0.5 / Math.PI; - d = 0.5; - x = zoomScale * (a * x + b) - 215440491; - y = -(zoomScale * (c * y + d) - 106744817); - return [x, y]; - } -} diff --git a/packages/maps/src/amap2/index.ts b/packages/maps/src/amap2/index.ts deleted file mode 100644 index a7f34dcfd57..00000000000 --- a/packages/maps/src/amap2/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { IAMapInstance } from '../types'; -import BaseMapWrapper from '../utils/BaseMapWrapper'; -import AMapService from './map'; - -export default class AMapWrapper2 extends BaseMapWrapper { - protected getServiceConstructor() { - return AMapService; - } -} diff --git a/packages/maps/src/amap2/map.ts b/packages/maps/src/amap2/map.ts deleted file mode 100644 index 5cc495a4fde..00000000000 --- a/packages/maps/src/amap2/map.ts +++ /dev/null @@ -1,419 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -/** - * AMapService - */ -import AMapLoader from '@amap/amap-jsapi-loader'; - -import type { Bounds, IMapCamera, IPoint, IViewport } from '@antv/l7-core'; -import { CoordinateSystem } from '@antv/l7-core'; -import { DOM, amap2Project } from '@antv/l7-utils'; -import type { vec2 } from 'gl-matrix'; -import { mat4, vec3 } from 'gl-matrix'; -import type { IAMapInstance } from '../types'; -import AMapBaseService from '../utils/amap/AMapBaseService'; -import Viewport from './Viewport'; -import './logo.css'; -const DEFAULTMAPCENTER = [108.92361, 34.54083]; - -// @ts-ignore -window.forceWebGL = true; -const AMAP_API_KEY: string = 'f59bcf249433f8b05caaee19f349b3d7'; -// 'ff533602d57df6f8ab3b0fea226ae52f'; -const AMAP_VERSION: string = '2.0'; - -/** - * 高德地图脚本是否加载完毕 - */ -const amapLoaded = false; -/** - * 高德地图脚本加载成功等待队列,成功之后依次触发 - */ -const pendingResolveQueue: Array<() => void> = []; - -/** - * AMapService - */ -export default class AMapService extends AMapBaseService { - public version: string = 'GAODE2.x'; - - /** - * 用于 customCooords 数据的计算 - */ - public sceneCenter!: [number, number]; // 一般使用用户数据的第一个 - public sceneCenterMercator!: [number, number]; // 莫卡托 - - protected viewport: Viewport; - - /** - * 设置数据的绘制中心 高德2.0 - */ - public setCustomCoordCenter(center: [number, number]) { - this.sceneCenter = center; - this.sceneCenterMercator = amap2Project(...center); - } - - public getCustomCoordCenter(): [number, number] { - return this.sceneCenterMercator; - } - - public lngLatToCoordByLayer(lnglat: number[], layerCenterMercator: [number, number]) { - const layerCenterFlat = layerCenterMercator || this.sceneCenterMercator; - const coord = this._sub(amap2Project(lnglat[0], lnglat[1]), layerCenterFlat); - // Z 参数 - if (lnglat[2]) { - coord.push(lnglat[2]); - } - return coord; - } - - public coordToAMap2RelativeCoordinates( - lnglatArray: number[][][] | number[][] | number[], - layerCenter: [number, number], - ): number[][][] | number[][] | number[] { - const layerCenterMercator = amap2Project(layerCenter[0], layerCenter[1]); - if (typeof lnglatArray[0] === 'number') { - return this.lngLatToCoordByLayer(lnglatArray as number[], layerCenterMercator); - } else { - // @ts-ignore - return lnglatArray.map((lnglats) => { - if (Array.isArray(lnglats) && typeof lnglats[0] === 'number') { - return this.lngLatToCoordByLayer(lnglats as number[], layerCenterMercator); - } else { - // @ts-ignore - return lnglats.map((lnglat) => { - return this.lngLatToCoordByLayer(lnglat as number[], layerCenterMercator); - }); - } - }); - } - } - - public setCoordCenter(center: [number, number]) { - // @ts-ignore - this.map.customCoords.setCenter(center || DEFAULTMAPCENTER); - this.setCustomCoordCenter(center || DEFAULTMAPCENTER); - } - - /** - * 根据数据的绘制中心转换经纬度数据 高德2.0 - */ - public lngLatToCoord(lnglat: [number, number]) { - // 单点 - if (!this.sceneCenter) { - // @ts-ignore - this.map.customCoords.setCenter(lnglat); - this.setCustomCoordCenter(lnglat); - } - return this._sub(amap2Project(lnglat[0], lnglat[1]), this.sceneCenterMercator); - } - - /** - * 转化线、面类型的点位数据 - */ - public lngLatToCoords(lnglatArray: number[][][] | number[][]): number[][][] | number[][] { - // @ts-ignore - return lnglatArray.map((lnglats) => { - if (typeof lnglats[0] === 'number') { - return this.lngLatToCoord(lnglats as [number, number]); - } else { - // @ts-ignore - return lnglats.map((lnglat) => { - return this.lngLatToCoord(lnglat as [number, number]); - }); - } - }); - } - - public addMarkerContainer(): void { - if (!this.map) { - return; - } - const mapContainer = this.map.getContainer(); - if (mapContainer !== null) { - const amap = mapContainer.getElementsByClassName('amap-maps')[0] as HTMLElement; - // amap2 的 amap-maps 新增 z-index=0; 样式,让 marker 中 zIndex 失效 - amap.style.zIndex = 'auto'; - this.markerContainer = DOM.create('div', 'l7-marker-container2', amap); - } - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - // tslint:disable-next-line:variable-name no-empty - public updateView(_viewOption: Partial): void {} - - public getOverlayContainer(): HTMLElement | undefined { - return undefined; - } - - public getType() { - return 'amap2'; - } - - public getBounds(): Bounds { - const bounds = this.map.getBounds(); - - // @ts-ignore - const NE = bounds.getNorthEast(); - // @ts-ignore - const SW = bounds.getSouthWest(); - const center = this.getCenter(); - const maxlng = - center.lng > NE.getLng() || center.lng < SW.getLng() ? 180 - NE.getLng() : NE.getLng(); - const minlng = center.lng < SW.getLng() ? SW.getLng() - 180 : SW.getLng(); - // 兼容 Mapbox,统一返回西南、东北 - return [ - [minlng, SW.getLat()], - [maxlng, NE.getLat()], - ]; - } - - public getMinZoom(): number { - // const zooms = this.map.get('zooms') as [number, number]; - // @ts-ignore - const zooms = this.map.getZooms() as [number, number]; - return zooms[0] - 1; - } - public getMaxZoom(): number { - // const zooms = this.map.get('zooms') as [number, number]; - // @ts-ignore - const zooms = this.map.getZooms() as [number, number]; - return zooms[1] - 1; - } - - public lngLatToContainer(lnglat: [number, number]): IPoint { - const pixel = this.map.lngLatToContainer(lnglat); - return { - x: pixel.getX(), - y: pixel.getY(), - }; - } - public lngLatToPixel(lnglat: [number, number]): IPoint { - // @ts-ignore - const p = this.map.lngLatToPixel(new AMap.LngLat(lnglat[0], lnglat[1])); - // lngLatToPixel - return { - x: p.getX(), - y: p.getY(), - }; - } - - public getModelMatrix( - lnglat: [number, number], - altitude: number, - rotate: [number, number, number], - scale: [number, number, number] = [1, 1, 1], - ): number[] { - // const flat = this.viewport.projectFlat(lnglat); - // @ts-ignore - const flat = this.map.customCoords.lngLatToCoord(lnglat); - // @ts-ignore - const modelMatrix = mat4.create(); - - mat4.translate(modelMatrix, modelMatrix, vec3.fromValues(flat[0], flat[1], altitude)); - - mat4.scale(modelMatrix, modelMatrix, vec3.fromValues(scale[0], scale[1], scale[2])); - - mat4.rotateX(modelMatrix, modelMatrix, rotate[0]); - mat4.rotateY(modelMatrix, modelMatrix, rotate[1]); - mat4.rotateZ(modelMatrix, modelMatrix, rotate[2]); - - return modelMatrix as unknown as number[]; - } - public async init(): Promise { - const { - id, - style = 'light', - minZoom = 0, - maxZoom = 24, - token = AMAP_API_KEY, - mapInstance, - plugin = [], - version = AMAP_VERSION, - ...rest - } = this.config; - this.viewport = new Viewport(); - if (!(window.AMap || mapInstance)) { - plugin.push('Map3D'); - // if (AMapLoader.status.AMap === 'notload') { - await AMapLoader.load({ - key: token, // 申请好的Web端开发者Key,首次调用 load 时必填 - version: AMAP_VERSION, // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15 - plugins: plugin, // 需要使用的的插件列表,如比例尺'AMap.Scale'等 - }); - } - if (mapInstance) { - this.map = mapInstance as AMap.Map & IAMapInstance; - this.$mapContainer = this.map.getContainer(); - - // 在使用 map.customCoords 的时候必须使用 - const mapInitCenter = this.map.getCenter(); - // @ts-ignore - this.map.customCoords?.setCenter([ - // @ts-ignore - mapInitCenter.lng, - // @ts-ignore - mapInitCenter.lat, - ]); - // @ts-ignore - this.setCustomCoordCenter([mapInitCenter.lng, mapInitCenter.lat]); - this.map.on('viewchange', this.handleViewChanged); - } else { - this.$mapContainer = this.creatMapContainer(id as string | HTMLDivElement); - const mapConstructorOptions = { - mapStyle: this.getMapStyleValue(style as string), - zooms: [minZoom, maxZoom], - viewMode: '3D', - ...rest, - }; - if (mapConstructorOptions.zoom) { - // 高德地图在相同大小下需要比 MapBox 多一个 zoom 层级 - mapConstructorOptions.zoom += 1; - } - if (token === AMAP_API_KEY) { - // @ts-ignore - window._AMapSecurityConfig = { - securityJsCode: '2653011adeb04230b3a26cc9a780a800', - }; - - console.warn( - `%c${this.configService.getSceneWarninfo('MapToken')}!`, - 'color: #873bf4;font-weigh:900;font-size: 16px;', - ); - } - // @ts-ignore - const map = new AMap.Map(this.$mapContainer, mapConstructorOptions); - // @ts-ignore - this.map = map; - // 在使用 map.customCoords 的时候必须使用 - const mapInitCenter = map.getCenter(); - // @ts-ignore - - // @ts-ignore - this.map.customCoords?.setCenter([mapInitCenter.lng, mapInitCenter.lat]); - - // @ts-ignore - this.setCustomCoordCenter([mapInitCenter.lng, mapInitCenter.lat]); - // 监听地图相机事件 - map.on('viewchange', this.handleViewChanged); - } - - this.initViewPort(); - } - - public getMapContainer() { - return this.$mapContainer; - } - - public onCameraChanged(callback: (viewport: IViewport) => void): void { - this.cameraChangedCallback = callback; - } - - private initViewPort() { - // @ts-ignore - const { - // @ts-ignore - fov, - // @ts-ignore - near, - // @ts-ignore - far, - // @ts-ignore - aspect, - // @ts-ignore - position, - // @ts-ignore - lookAt, - // @ts-ignore - up, - // @ts-ignore - // left, right, bottom, top - // @ts-ignore - } = this.map.customCoords?.getCameraParams() || {}; - // Tip: 统一触发地图变化事件 - this.emit('mapchange'); - // @ts-ignore - const center = this.map.customCoords.getCenter() as [number, number]; - const zoom = this.map.getZoom(); - // @ts-ignore - if (this.cameraChangedCallback) { - this.viewport.syncWithMapCamera({ - aspect, - far, - fov, - cameraPosition: position, - lookAt, - near, - up, - // AMap 定义的缩放等级 与 Mapbox 相差 1 - zoom: zoom - 1, // 与amap1.x对比相差一个级别 - center, - offsetOrigin: [position[0], position[1]], - - // @ts-ignore - // left, right, bottom, top - }); - // set coordinate system - this.coordinateSystemService.setCoordinateSystem(CoordinateSystem.P20_2); - this.cameraChangedCallback(this.viewport); - } - } - - private _sub(a: number[] | vec3 | vec2, b: number[]): [number, number] { - const r: [number, number] = [0, 0]; - r[0] = a[0] - b[0]; - r[1] = a[1] - b[1]; - return r; - } - - /** - * - * @param e - */ - private handleViewChanged = (e: any): void => { - const { - // @ts-ignore - fov, - // @ts-ignore - near, - // @ts-ignore - far, - // @ts-ignore - aspect, - // @ts-ignore - position, - // @ts-ignore - lookAt, - // @ts-ignore - up, - // @ts-ignore - // left, right, bottom, top - // @ts-ignore - } = this.map.customCoords.getCameraParams(); - // Tip: 统一触发地图变化事件 - this.emit('mapchange'); - // @ts-ignore - const center = this.map.customCoords.getCenter() as [number, number]; - if (this.cameraChangedCallback) { - // resync viewport - this.viewport.syncWithMapCamera({ - aspect, - far, - fov, - cameraPosition: position, - lookAt, - up, - near, - // AMap 定义的缩放等级 与 Mapbox 相差 1 - zoom: this.map.getZoom() - 1, // 与amap1.x对比相差一个级别 - center, - offsetOrigin: [position[0], position[1]], - - // @ts-ignore - // left, right, bottom, top - }); - // set coordinate system - this.coordinateSystemService.setCoordinateSystem(CoordinateSystem.P20_2); - this.cameraChangedCallback(this.viewport); - } - }; -} diff --git a/packages/maps/src/bmap/index.ts b/packages/maps/src/bmap/index.ts index 6abba1cbc1f..744d924b71b 100644 --- a/packages/maps/src/bmap/index.ts +++ b/packages/maps/src/bmap/index.ts @@ -1,7 +1,6 @@ -import type { Map } from '@antv/l7-map'; import BaseMapWrapper from '../utils/BaseMapWrapper'; import MapService from './map'; -export default class MapboxWrapper extends BaseMapWrapper { +export default class MapboxWrapper extends BaseMapWrapper { protected getServiceConstructor() { return MapService; } diff --git a/packages/maps/src/bmap/map.ts b/packages/maps/src/bmap/map.ts index 2aea81e89af..47d028378db 100644 --- a/packages/maps/src/bmap/map.ts +++ b/packages/maps/src/bmap/map.ts @@ -13,8 +13,8 @@ import type { import { MapServiceEvent } from '@antv/l7-core'; import { DOM } from '@antv/l7-utils'; import { mat4, vec3 } from 'gl-matrix'; +import Viewport from '../lib/web-mercator-viewport'; import BaseMapService from '../utils/BaseMapService'; -import Viewport from '../utils/Viewport'; import { toPaddingOptions } from '../utils/utils'; import BMapGLLoader from './bmapglloader'; import './logo.css'; @@ -31,6 +31,7 @@ const EventMap: { const BMAP_API_KEY: string = 'zLhopYPPERGtpGOgimcdKcCimGRyyIsh'; const BMAP_VERSION: string = '1.0'; +// TODO: 基于抽象类 BaseMap 实现,补全缺失方法,解决类型问题 export default class BMapService extends BaseMapService { protected viewport: IViewport; protected styleConfig: Record = { diff --git a/packages/maps/src/earth/map.ts b/packages/maps/src/earth/map.ts index 9cd05b0801e..77c27175190 100644 --- a/packages/maps/src/earth/map.ts +++ b/packages/maps/src/earth/map.ts @@ -4,8 +4,7 @@ */ import type { IEarthService, IMercator, IViewport } from '@antv/l7-core'; import { CoordinateSystem, MapServiceEvent } from '@antv/l7-core'; -import type { Map } from '@antv/l7-map'; -import { EarthMap } from '@antv/l7-map'; +import { Map } from '@antv/l7-map'; import BaseMapService from '../utils/BaseMapService'; import Viewport from './Viewport'; const EventMap: { @@ -77,10 +76,8 @@ export default class L7EarthService extends BaseMapService implements IEart this.viewport = new Viewport(); this.$mapContainer = this.creatMapContainer(id); - // @ts-ignore - this.map = new EarthMap({ + this.map = new Map({ container: this.$mapContainer, - style: this.getMapStyleValue(style), bearing: rotation, ...rest, }); diff --git a/packages/maps/src/gmap/map.ts b/packages/maps/src/gmap/map.ts index 58f12fa3faa..aa9492e0d1c 100644 --- a/packages/maps/src/gmap/map.ts +++ b/packages/maps/src/gmap/map.ts @@ -12,8 +12,8 @@ import { MapServiceEvent } from '@antv/l7-core'; import { MercatorCoordinate } from '@antv/l7-map'; import { DOM } from '@antv/l7-utils'; import { mat4, vec3 } from 'gl-matrix'; +import Viewport from '../lib/web-mercator-viewport'; import BaseMapService from '../utils/BaseMapService'; -import Viewport from '../utils/Viewport'; import './logo.css'; import GMapLoader from './maploader'; @@ -28,6 +28,7 @@ const EventMap: { dragging: 'drag', }; +// TODO: 基于抽象类 BaseMap 实现,补全缺失方法,解决类型问题 export default class TMapService extends BaseMapService { // @ts-ignore protected viewport: IViewport = null; diff --git a/packages/maps/src/index.ts b/packages/maps/src/index.ts index ddab097fe73..c30deff0a33 100644 --- a/packages/maps/src/index.ts +++ b/packages/maps/src/index.ts @@ -1,6 +1,4 @@ -import { MapType } from '@antv/l7-utils'; -import GaodeMapV1 from './amap/'; -import { default as GaodeMap, default as GaodeMapV2 } from './amap2/'; +import { default as GaodeMapNext } from './amap-next'; import BaiduMap from './bmap/'; import Earth from './earth/'; import GoogleMap from './gmap'; @@ -9,7 +7,23 @@ import Mapbox from './mapbox/'; import MapLibre from './maplibre'; import TMap from './tdtmap'; import TencentMap from './tmap'; +import type { MapType } from './types'; export * from './utils'; + +const GaodeMap = GaodeMapNext; + +/** + * @deprecated + * 不再支持 GaodeMapV1,自动指向最新版 GaodeMap V2 + */ +const GaodeMapV1 = GaodeMapNext; + +/** + * @deprecated + * 不再暴露 GaodeMapV2,默认自动指向最新版 GaodeMap + */ +const GaodeMapV2 = GaodeMapNext; + export { BaiduMap, Earth, diff --git a/packages/maps/src/lib/base-map.ts b/packages/maps/src/lib/base-map.ts new file mode 100644 index 00000000000..cc4865b5ab5 --- /dev/null +++ b/packages/maps/src/lib/base-map.ts @@ -0,0 +1,228 @@ +import type { + Bounds, + ICoordinateSystemService, + IGlobalConfigService, + ILngLat, + IMapCamera, + IMapConfig, + IMapService, + IMercator, + IPoint, + IStatusOptions, + IViewport, + L7Container, + MapStyleConfig, + MapStyleName, +} from '@antv/l7-core'; +import { CoordinateSystem } from '@antv/l7-core'; +import type { EventEmitterStatic } from 'eventemitter3'; +import { EventEmitter } from 'eventemitter3'; +import { SimpleMapCoord } from '../utils/simpleMapCoord'; + +const LNGLAT_OFFSET_ZOOM_THRESHOLD = 12; + +export default abstract class BaseMap implements IMapService { + /** + * 地图实例 + */ + public map: T; + + /** + * @deprecated + * TODO: 基类型不需要实现,只是自定义 Map 使用非地理坐标系才会用到 + */ + public simpleMapCoord = new SimpleMapCoord(); + + /** + * 背景色 + */ + public bgColor = 'rgba(0.0, 0.0, 0.0, 0.0)'; + + protected abstract viewport: IViewport; + + protected readonly config: Partial>; + + protected readonly configService: IGlobalConfigService; + + protected readonly coordinateSystemService: ICoordinateSystemService; + + protected eventEmitter: InstanceType; + + protected markerContainer: HTMLElement; + + protected mapContainer: HTMLElement | null; + + protected cameraChangedCallback?: (viewport: IViewport) => void; + + constructor(container: L7Container) { + this.config = container.mapConfig as Partial>; + this.configService = container.globalConfigService; + this.coordinateSystemService = container.coordinateSystemService; + this.eventEmitter = new EventEmitter(); + } + + public abstract init(): Promise; + + public onCameraChanged(callback: (viewport: IViewport) => void): void { + this.cameraChangedCallback = callback; + } + + protected abstract handleCameraChanged: () => void; + + public updateView(viewOption: Partial) { + this.emit('mapchange'); + this.viewport.syncWithMapCamera({ + bearing: viewOption.bearing, + center: viewOption.center, + viewportHeight: viewOption.viewportHeight, + pitch: viewOption.pitch, + viewportWidth: viewOption.viewportWidth, + zoom: viewOption.zoom, + }); + this.updateCoordinateSystemService(); + this.cameraChangedCallback?.(this.viewport); + } + + protected updateCoordinateSystemService() { + const { offsetCoordinate = true } = this.config; + // set coordinate system + if (this.viewport.getZoom() > LNGLAT_OFFSET_ZOOM_THRESHOLD && offsetCoordinate) { + this.coordinateSystemService.setCoordinateSystem(CoordinateSystem.LNGLAT_OFFSET); + } else { + this.coordinateSystemService.setCoordinateSystem(CoordinateSystem.LNGLAT); + } + } + + protected creatMapContainer(id: string | HTMLDivElement) { + let $wrapper: HTMLDivElement; + + if (typeof id === 'string') { + $wrapper = document.getElementById(id) as HTMLDivElement; + } else { + $wrapper = id; + } + + return $wrapper; + } + + public abstract getMapStyle(): string; + + public abstract getMapStyleConfig(): MapStyleConfig; + + public getMapStyleValue(name: MapStyleName): any { + return this.getMapStyleConfig()[name] ?? name; + } + + public abstract getType(): string; + + public setBgColor(color: string) { + this.bgColor = color; + } + + public abstract getContainer(): HTMLElement | null; + + public getMapContainer() { + return this.mapContainer; + } + + public abstract getMapCanvasContainer(): HTMLElement; + + public abstract addMarkerContainer(): void; + + public getMarkerContainer(): HTMLElement { + return this.markerContainer; + } + + public getOverlayContainer(): HTMLElement | undefined { + return undefined; + } + + public getCanvasOverlays(): HTMLElement | null | undefined { + return undefined; + } + + public abstract on(type: string, handle: (...args: any[]) => void): void; + + public abstract off(type: string, handle: (...args: any[]) => void): void; + + public emit(name: string, ...args: any[]) { + this.eventEmitter.emit(name, ...args); + } + + public once(name: string, handler: (...args: any[]) => void) { + this.eventEmitter.once(name, handler); + } + + public abstract getSize(): [number, number]; + + public abstract getZoom(): number; + + public abstract setZoom(zoom: number): void; + + public abstract getCenter(): ILngLat; + + public abstract setCenter(lnglat: [number, number]): void; + + public abstract getPitch(): number; + + public abstract getRotation(): number; + + public abstract getBounds(): Bounds; + + public abstract getMinZoom(): number; + + public abstract getMaxZoom(): number; + + public abstract setRotation(rotation: number): void; + + public abstract zoomIn(option?: any, eventData?: any): void; + + public abstract zoomOut(option?: any, eventData?: any): void; + + public abstract setPitch(pitch: number): void; + + public abstract panTo(p: [number, number]): void; + + public abstract panBy(x: number, y: number): void; + + public abstract fitBounds(bound: Bounds, fitBoundsOptions?: any): void; + + public abstract setMaxZoom(max: number): void; + + public abstract setMinZoom(min: number): void; + + public abstract setMapStatus(option: Partial): void; + + public abstract setZoomAndCenter(zoom: number, center: [number, number]): void; + + public abstract setMapStyle(name: MapStyleName): void; + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public meterToCoord(center: [number, number], outer: [number, number]) { + return 1.0; + } + + public abstract pixelToLngLat(pixel: [number, number]): ILngLat; + + public abstract lngLatToPixel(lnglat: [number, number]): IPoint; + + public abstract containerToLngLat(pixel: [number, number]): ILngLat; + + public abstract lngLatToContainer(lnglat: [number, number]): IPoint; + + public abstract lngLatToMercator(lnglat: [number, number], altitude: number): IMercator; + + public abstract getModelMatrix( + lnglat: [number, number], + altitude: number, + rotate: [number, number, number], + scale: [number, number, number], + origin: IMercator, + ): number[]; + + public abstract exportMap(type: 'jpg' | 'png'): string; + + public destroy() { + this.eventEmitter.removeAllListeners(); + } +} diff --git a/packages/maps/src/mapbox/Viewport.ts b/packages/maps/src/lib/web-mercator-viewport.ts similarity index 82% rename from packages/maps/src/mapbox/Viewport.ts rename to packages/maps/src/lib/web-mercator-viewport.ts index 32f0b106448..f80e3f1d045 100644 --- a/packages/maps/src/mapbox/Viewport.ts +++ b/packages/maps/src/lib/web-mercator-viewport.ts @@ -2,16 +2,23 @@ import type { IMapCamera, IViewport } from '@antv/l7-core'; import WebMercatorViewport from 'viewport-mercator-project'; export default class Viewport implements IViewport { - public viewport: WebMercatorViewport; + public viewport = new WebMercatorViewport(); public syncWithMapCamera(mapCamera: Partial) { const { center, zoom, pitch, bearing, viewportHeight, viewportWidth } = mapCamera; - /** - * Deck.gl 使用的也是 Mapbox 同步相机,相机参数保持一致 - * 例如相机高度固定为 height * 1.5,因此不需要传 - */ + const preView = { + width: this.viewport.width, + height: this.viewport.height, + longitude: this.viewport.center[0], + latitude: this.viewport.center[1], + zoom: this.viewport.zoom, + pitch: this.viewport.pitch, + bearing: this.viewport.bearing, + }; + this.viewport = new WebMercatorViewport({ + ...preView, width: viewportWidth, height: viewportHeight, longitude: center && center[0], @@ -50,6 +57,7 @@ export default class Viewport implements IViewport { // @ts-ignore return this.viewport.viewMatrixUncentered; } + public getViewProjectionMatrix(): number[] { // @ts-ignore return this.viewport.viewProjectionMatrix; @@ -59,6 +67,7 @@ export default class Viewport implements IViewport { // @ts-ignore return this.viewport.viewProjectionMatrix; } + public getFocalDistance() { return 1; } diff --git a/packages/maps/src/map/map.ts b/packages/maps/src/map/map.ts index 7a2259cbd42..582ae587997 100644 --- a/packages/maps/src/map/map.ts +++ b/packages/maps/src/map/map.ts @@ -4,14 +4,12 @@ */ import type { IMercator } from '@antv/l7-core'; import { Map, MercatorCoordinate } from '@antv/l7-map'; -import { MapType } from '@antv/l7-utils'; import { mat4, vec3 } from 'gl-matrix'; +import Viewport from '../lib/web-mercator-viewport'; +import { MapType } from '../types'; import BaseMapService from '../utils/BaseMapService'; -import Viewport from '../utils/Viewport'; -/** - * AMapService - */ +// TODO: 基于抽象类 BaseMap 实现 export default class DefaultMapService extends BaseMapService { public version: string = MapType.DEFAULT; /** @@ -91,10 +89,8 @@ export default class DefaultMapService extends BaseMapService { this.$mapContainer = this.map.getContainer(); } else { this.$mapContainer = this.creatMapContainer(id); - // @ts-ignore this.map = new Map({ container: this.$mapContainer, - style: this.getMapStyleValue(style), bearing: rotation, ...rest, }); @@ -115,15 +111,28 @@ export default class DefaultMapService extends BaseMapService { this.handleCameraChanged(); } + protected creatMapContainer(id: string | HTMLDivElement) { + let wrapper = id as HTMLDivElement; + if (typeof id === 'string') { + wrapper = document.getElementById(id) as HTMLDivElement; + } + const container = document.createElement('div'); + container.style.cssText += ` + position: absolute; + top: 0; + height: 100%; + width: 100%; + `; + wrapper.appendChild(container); + return container; + } + public exportMap(type: 'jpg' | 'png'): string { - const renderCanvas = this.map.getCanvas(); - const layersPng = - type === 'jpg' - ? (renderCanvas?.toDataURL('image/jpeg') as string) - : (renderCanvas?.toDataURL('image/png') as string); - return layersPng; + return ''; } + public setMapStyle(style: any): void {} + public getCanvasOverlays() { return this.getContainer(); } diff --git a/packages/maps/src/mapbox/map.ts b/packages/maps/src/mapbox/map.ts index 4d82b62188c..6be734b068b 100644 --- a/packages/maps/src/mapbox/map.ts +++ b/packages/maps/src/mapbox/map.ts @@ -6,17 +6,16 @@ import { mat4, vec3 } from 'gl-matrix'; import type { Map } from 'mapbox-gl'; import mapboxgl from 'mapbox-gl'; import 'mapbox-gl/dist/mapbox-gl.css'; +import Viewport from '../lib/web-mercator-viewport'; import type { IMapboxInstance } from '../types'; import BaseMapService from '../utils/BaseMapService'; -import Viewport from './Viewport'; window.mapboxgl = mapboxgl; let mapdivCount = 0; const MAPBOX_API_KEY = '101MlGsZ2AmmA&access_token=pk.eyJ1IjoiZXhhbXBsZXMiLCJhIjoiY2p0MG01MXRqMW45cjQzb2R6b2ptc3J4MSJ9.zA2W0IkI0c6KaAhJfk9bWg'; -/** - * AMapService - */ + +// TODO: 基于抽象类 BaseMap 实现 export default class MapboxService extends BaseMapService { public version: string = 'MAPBOX'; // get mapStatus method diff --git a/packages/maps/src/maplibre/map.ts b/packages/maps/src/maplibre/map.ts index 0cde9686931..9850456f47c 100644 --- a/packages/maps/src/maplibre/map.ts +++ b/packages/maps/src/maplibre/map.ts @@ -2,22 +2,20 @@ * MapboxService */ import type { IMercator } from '@antv/l7-core'; -import { MapType } from '@antv/l7-utils'; import { mat4, vec3 } from 'gl-matrix'; import type { Map } from 'maplibre-gl'; import maplibregl from 'maplibre-gl'; import 'maplibre-gl/dist/maplibre-gl.css'; -import Viewport from '../mapbox/Viewport'; -import type { IMapboxInstance } from '../types'; +import Viewport from '../lib/web-mercator-viewport'; +import { MapType, type IMapboxInstance } from '../types'; import BaseMapService from '../utils/BaseMapService'; // @ts-ignore window.maplibregl = maplibregl; let mapdivCount = 0; -/** - * AMapService - */ + +// TODO: 基于抽象类 BaseMap 实现 export default class Service extends BaseMapService { public version: string = MapType.MAPBOX; // get mapStatus method diff --git a/packages/maps/src/tdtmap/map.ts b/packages/maps/src/tdtmap/map.ts index 217da8de44d..45c47ef026e 100644 --- a/packages/maps/src/tdtmap/map.ts +++ b/packages/maps/src/tdtmap/map.ts @@ -11,7 +11,7 @@ import type { } from '@antv/l7-core'; import { MapServiceEvent } from '@antv/l7-core'; import { MercatorCoordinate } from '@antv/l7-map'; -import Viewport from '../utils/Viewport'; +import Viewport from '../lib/web-mercator-viewport'; import { load } from './maploader'; let mapdivCount: number = 0; @@ -22,6 +22,7 @@ const EventMap: { zoomchange: ['Ge'], }; +// TODO: 基于抽象类 BaseMap 实现,补全缺失方法,解决类型问题 export default class TdtMapService extends BaseMapService { protected viewport: IViewport | null = null; protected evtCbProxyMap: Map any, (...args: any) => any>> = @@ -312,7 +313,15 @@ export default class TdtMapService extends BaseMapService { } public setCenter(lnglat: [number, number]): void { - this.map.setCenter(lnglat); + // @ts-ignore + const lngLat = window.T.LngLat(lnglat[0], lnglat[1]); + this.map.centerAndZoom(lngLat, this.map.getZoom()); + } + + public setZoomAndCenter(zoom: number, center: [number, number]) { + // @ts-ignore + const lngLat = window.T.LngLat(center[0], center[1]); + this.map.centerAndZoom(lngLat, zoom); } public getPitch(): number { diff --git a/packages/maps/src/tmap/map.ts b/packages/maps/src/tmap/map.ts index 05b9dc792f3..ff0451747ae 100644 --- a/packages/maps/src/tmap/map.ts +++ b/packages/maps/src/tmap/map.ts @@ -12,8 +12,8 @@ import { MapServiceEvent } from '@antv/l7-core'; import { MercatorCoordinate } from '@antv/l7-map'; import { DOM } from '@antv/l7-utils'; import { mat4, vec3 } from 'gl-matrix'; +import Viewport from '../lib/web-mercator-viewport'; import BaseMapService from '../utils/BaseMapService'; -import Viewport from '../utils/Viewport'; import './logo.css'; import TMapLoader from './maploader'; @@ -29,6 +29,7 @@ const EventMap: { dragging: 'drag', }; +// TODO: 基于抽象类 BaseMap 实现,补全缺失方法,解决类型问题 export default class TMapService extends BaseMapService { // @ts-ignore protected viewport: IViewport = null; diff --git a/packages/maps/src/types.ts b/packages/maps/src/types.ts index 2df290558bf..4cbf9b622a7 100644 --- a/packages/maps/src/types.ts +++ b/packages/maps/src/types.ts @@ -1,5 +1,13 @@ import type { IControl } from 'mapbox-gl'; +export enum MapType { + 'GAODE' = 'GAODE', + 'MAPBOX' = 'MAPBOX', + 'DEFAULT' = 'DEFAUlTMAP', + 'SIMPLE' = 'SIMPLE', + 'GLOBEL' = 'GLOBEL', +} + export interface IAMapEvent { camera: { fov: number; diff --git a/packages/maps/src/utils/BaseMapService.ts b/packages/maps/src/utils/BaseMapService.ts index b8e2300974a..b4a82233dca 100644 --- a/packages/maps/src/utils/BaseMapService.ts +++ b/packages/maps/src/utils/BaseMapService.ts @@ -34,9 +34,7 @@ const EventMap: { }; const LNGLAT_OFFSET_ZOOM_THRESHOLD = 12; -/** - * AMapService - */ + export default abstract class BaseMapService implements IMapService { public version: string = 'DEFAUlTMAP'; public map: Map & T; @@ -176,7 +174,6 @@ export default abstract class BaseMapService implements IMapService } public panBy(x: number = 0, y: number = 0): void { - // @ts-ignore this.map.panBy([x, y]); } @@ -232,7 +229,8 @@ export default abstract class BaseMapService implements IMapService } public setMapStyle(style: any): void { - this.map.setStyle(this.getMapStyleValue(style)); + // @ts-ignore + this.map?.setStyle(this.getMapStyleValue(style)); } // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -309,7 +307,8 @@ export default abstract class BaseMapService implements IMapService } public exportMap(type: 'jpg' | 'png'): string { - const renderCanvas = this.map.getCanvas(); + // @ts-ignore + const renderCanvas = this.map?.getCanvas(); const layersPng = type === 'jpg' ? (renderCanvas?.toDataURL('image/jpeg') as string) diff --git a/packages/maps/src/utils/BaseMapWrapper.ts b/packages/maps/src/utils/BaseMapWrapper.ts index 0a586aaa3b6..4bd45c65d18 100644 --- a/packages/maps/src/utils/BaseMapWrapper.ts +++ b/packages/maps/src/utils/BaseMapWrapper.ts @@ -14,16 +14,11 @@ export default class BaseMapWrapper implements IMapWrapper { this.config = config; } - public setContainer( - sceneContainer: L7Container, - id: string | HTMLDivElement, - canvas?: HTMLCanvasElement, - ) { + public setContainer(sceneContainer: L7Container, id: string | HTMLDivElement) { this.configService = sceneContainer.globalConfigService; sceneContainer.mapConfig = { ...this.config, id, - canvas, }; // @ts-ignore sceneContainer.mapService = new (this.getServiceConstructor())(sceneContainer); diff --git a/packages/maps/src/utils/Viewport.ts b/packages/maps/src/utils/Viewport.ts deleted file mode 100644 index 10034f8d0a9..00000000000 --- a/packages/maps/src/utils/Viewport.ts +++ /dev/null @@ -1,86 +0,0 @@ -import type { IMapCamera, IViewport } from '@antv/l7-core'; -import WebMercatorViewport from 'viewport-mercator-project'; - -export default class Viewport implements IViewport { - public viewport: WebMercatorViewport; - - public syncWithMapCamera(mapCamera: Partial) { - const { center, zoom, pitch, bearing, viewportHeight, viewportWidth } = mapCamera; - - const preView = this.viewport - ? { - width: this.viewport.width, - height: this.viewport.height, - longitude: this.viewport.center[0], - latitude: this.viewport.center[1], - zoom: this.viewport.zoom, - pitch: this.viewport.pitch, - bearing: this.viewport.bearing, - } - : {}; - - /** - * Deck.gl 使用的也是 Mapbox 同步相机,相机参数保持一致 - * 例如相机高度固定为 height * 1.5,因此不需要传 - */ - this.viewport = new WebMercatorViewport({ - ...preView, - width: viewportWidth, - height: viewportHeight, - longitude: center && center[0], - latitude: center && center[1], - zoom, - pitch, - bearing, - }); - } - - public getZoom(): number { - return this.viewport.zoom; - } - - public getZoomScale(): number { - return Math.pow(2, this.getZoom()); - } - - public getCenter(): [number, number] { - return [this.viewport.longitude, this.viewport.latitude]; - } - - public getProjectionMatrix(): number[] { - return this.viewport.projectionMatrix; - } - - public getModelMatrix(): number[] { - return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; - } - - public getViewMatrix(): number[] { - return this.viewport.viewMatrix; - } - - public getViewMatrixUncentered(): number[] { - // @ts-ignore - return this.viewport.viewMatrixUncentered; - } - public getViewProjectionMatrix(): number[] { - // @ts-ignore - return this.viewport.viewProjectionMatrix; - } - - public getViewProjectionMatrixUncentered(): number[] { - // @ts-ignore - return this.viewport.viewProjectionMatrix; - } - public getFocalDistance() { - return 1; - } - - /** - * P20 坐标系,固定 scale - */ - - public projectFlat(lngLat: [number, number], scale?: number | undefined): [number, number] { - return this.viewport.projectFlat(lngLat, scale); - } -} diff --git a/packages/maps/src/utils/amap/AMapBaseService.ts b/packages/maps/src/utils/amap/AMapBaseService.ts deleted file mode 100644 index eb28a25890e..00000000000 --- a/packages/maps/src/utils/amap/AMapBaseService.ts +++ /dev/null @@ -1,552 +0,0 @@ -/** - * AMapService - */ -import AMapLoader from '@amap/amap-jsapi-loader'; -import type { - Bounds, - ICameraOptions, - ICoordinateSystemService, - IGlobalConfigService, - ILngLat, - IMapCamera, - IMapConfig, - IMapService, - IMercator, - IPoint, - IStatusOptions, - IViewport, - L7Container, - MapStyleConfig, - MapStyleName, -} from '@antv/l7-core'; -import { CoordinateSystem, MapServiceEvent } from '@antv/l7-core'; -import { DOM, MapType } from '@antv/l7-utils'; -import { EventEmitter } from 'eventemitter3'; -import { mat4, vec3 } from 'gl-matrix'; -import type { IAMapEvent, IAMapInstance } from '../../types'; -import Viewport from '../Viewport'; -import type { ISimpleMapCoord } from '../simpleMapCoord'; -import { SimpleMapCoord } from '../simpleMapCoord'; -import { toPaddingOptions } from '../utils'; -import './logo.css'; -import { MapTheme } from './theme'; -const AMapEventMapV1: { - [key: string]: any; -} = { - contextmenu: 'rightclick', -}; - -const AMapEventMapV2: { - [key: string]: any; -} = { - contextmenu: 'rightclick', - camerachange: 'viewchange', -}; - -const MapEventProxyMap: { - [key: string]: any; -} = { - 'GAODE1.x': AMapEventMapV1, - 'GAODE2.x': AMapEventMapV2, -}; - -let mapdivCount = 0; -// @ts-ignore -window.forceWebGL = true; - -const AMAP_API_KEY: string = '15cd8a57710d40c9b7c0e3cc120f1200'; -const AMAP_VERSION: string = '1.4.15'; -/** - * 确保多个场景只引入一个高德地图脚本 - */ -const AMAP_SCRIPT_ID: string = 'amap-script'; -/** - * 高德地图脚本是否加载完毕 - */ -let amapLoaded = false; -/** - * 高德地图脚本加载成功等待队列,成功之后依次触发 - */ -let pendingResolveQueue: Array<() => void> = []; -const LNGLAT_OFFSET_ZOOM_THRESHOLD = 12; // 暂时关闭 fix 统一不同坐标系,不同底图的高度位置 - -/** - * AMapService - */ -export default abstract class AMapBaseService implements IMapService { - public version: string = MapType['GAODE1.x']; - public simpleMapCoord: ISimpleMapCoord = new SimpleMapCoord(); - /** - * 原始地图实例 - */ - public map: AMap.Map & IAMapInstance; - - // 背景色 - public bgColor: string = 'rgba(0, 0, 0, 0)'; - - constructor(container: L7Container) { - this.config = container.mapConfig; - this.configService = container.globalConfigService; - this.coordinateSystemService = container.coordinateSystemService; - this.eventEmitter = new EventEmitter(); - } - - protected readonly configService: IGlobalConfigService; - protected readonly config: Partial; - protected readonly coordinateSystemService: ICoordinateSystemService; - protected eventEmitter: any; - - protected markerContainer: HTMLElement; - protected $mapContainer: HTMLElement | null; - - protected abstract viewport: IViewport; - - protected cameraChangedCallback: (viewport: IViewport) => void; - - public setBgColor(color: string) { - this.bgColor = color; - } - - public addMarkerContainer(): void { - const mapContainer = this.map.getContainer(); - if (mapContainer !== null) { - const amap = mapContainer.getElementsByClassName('amap-maps')[0] as HTMLElement; - this.markerContainer = DOM.create('div', 'l7-marker-container', amap); - } - } - public getMarkerContainer(): HTMLElement { - return this.markerContainer; - } - - // map event - public on(type: string, handler: (...args: any[]) => void): void { - if (MapServiceEvent.indexOf(type) !== -1) { - this.eventEmitter.on(type, handler); - } else { - this.map.on(MapEventProxyMap[this.version][type] || type, handler); - } - } - public off(type: string, handler: (...args: any[]) => void): void { - if (MapServiceEvent.indexOf(type) !== -1) { - this.eventEmitter.off(type, handler); - } else { - this.map.off(MapEventProxyMap[this.version][type] || type, handler); - } - } - - public getContainer(): HTMLElement | null { - return this.map.getContainer(); - } - - public getMapCanvasContainer(): HTMLElement { - return this.map.getContainer()?.getElementsByClassName('amap-maps')[0] as HTMLElement; - } - - public getCanvasOverlays() { - return this.$mapContainer?.querySelector('.amap-overlays') as HTMLElement; - } - - public getSize(): [number, number] { - const size = this.map.getSize(); - return [size.getWidth(), size.getHeight()]; - } - - public getType() { - return 'amap'; - } - public getZoom(): number { - // 统一返回 Mapbox 缩放等级 - return this.map.getZoom() - 1; - } - - public setZoom(zoom: number): void { - // 统一设置 Mapbox 缩放等级 - return this.map.setZoom(zoom + 1); - } - - public getCenter(options?: ICameraOptions): ILngLat { - if (options?.padding) { - const originCenter = this.getCenter(); - const padding = toPaddingOptions(options.padding); - const px = this.lngLatToPixel([originCenter.lng, originCenter.lat]); - const offsetPx = [(padding.right - padding.left) / 2, (padding.bottom - padding.top) / 2]; - - const newCenter = this.pixelToLngLat([px.x - offsetPx[0], px.y - offsetPx[1]]); - return newCenter; - } - const center = this.map.getCenter(); - return { - lng: center.getLng(), - lat: center.getLat(), - }; - } - public setCenter(lnglat: [number, number], options?: ICameraOptions): void { - if (options?.padding) { - const padding = toPaddingOptions(options.padding); - const px = this.lngLatToPixel(lnglat); - const offsetPx = [(padding.right - padding.left) / 2, (padding.bottom - padding.top) / 2]; - const newCenter = this.pixelToLngLat([px.x + offsetPx[0], px.y + offsetPx[1]]); - this.map.setCenter([newCenter.lng, newCenter.lat]); - } else { - this.map.setCenter(lnglat); - } - } - public getPitch(): number { - return this.map.getPitch(); - } - - public getRotation(): number { - // 统一返回逆时针旋转角度 - return 360 - this.map.getRotation(); - } - - public getBounds(): Bounds { - // @ts-ignore - const amapBound = this.map.getBounds().toBounds(); - const NE = amapBound.getNorthEast(); - const SW = amapBound.getSouthWest(); - const center = this.getCenter(); - const maxlng = - center.lng > NE.getLng() || center.lng < SW.getLng() ? 180 - NE.getLng() : NE.getLng(); - const minlng = center.lng < SW.getLng() ? SW.getLng() - 180 : SW.getLng(); - // 兼容 Mapbox,统一返回西南、东北 - return [ - [minlng, SW.getLat()], - [maxlng, NE.getLat()], - ]; - } - - public getMinZoom(): number { - const zooms = this.map.get('zooms') as [number, number]; - return zooms[0] - 1; - } - public getMaxZoom(): number { - const zooms = this.map.get('zooms') as [number, number]; - return zooms[1] - 1; - } - public setRotation(rotation: number): void { - return this.map.setRotation(rotation); - } - - public setPitch(pitch: number) { - return this.map.setPitch(pitch); - } - public zoomIn(): void { - this.map.zoomIn(); - } - - public zoomOut(): void { - this.map.zoomOut(); - } - - public panTo(p: [number, number]): void { - this.map.panTo(p); - } - - public panBy(x: number = 0, y: number = 0): void { - this.map.panBy(x, y); - } - - public fitBounds(extent: Bounds): void { - this.map.setBounds(new AMap.Bounds([extent[0][0], extent[0][1], extent[1][0], extent[1][1]])); - } - - public setZoomAndCenter(zoom: number, center: [number, number]): void { - this.map.setZoomAndCenter(zoom + 1, center); - } - - public setMapStyle(style: MapStyleName): void { - this.map.setMapStyle(this.getMapStyleValue(style)); - } - - public setMapStatus(option: Partial): void { - this.map.setStatus(option); - } - - public getMapStyleConfig(): MapStyleConfig { - return MapTheme; - } - - public getMapStyleValue(name: MapStyleName) { - return this.getMapStyleConfig()[name] || name; - } - - public getMapStyle(): string { - return this.map.getMapStyle(); - } - - public pixelToLngLat(pixel: [number, number]): ILngLat { - const lngLat = this.map.pixelToLngLat(new AMap.Pixel(pixel[0], pixel[1])); - return { lng: lngLat.getLng(), lat: lngLat.getLat() }; - } - public lngLatToPixel(lnglat: [number, number]): IPoint { - const p = this.map.lnglatToPixel(new AMap.LngLat(lnglat[0], lnglat[1])); - // lngLatToPixel - return { - x: p.getX(), - y: p.getY(), - }; - } - public containerToLngLat(pixel: [number, number]): ILngLat { - const ll = new AMap.Pixel(pixel[0], pixel[1]); - const lngLat = this.map.containerToLngLat(ll); - return { - lng: lngLat?.getLng(), - lat: lngLat?.getLat(), - }; - } - public lngLatToContainer(lnglat: [number, number]): IPoint { - const ll = new AMap.LngLat(lnglat[0], lnglat[1]); - const pixel = this.map.lngLatToContainer(ll); - return { - x: pixel.getX(), - y: pixel.getY(), - }; - } - - public lngLatToCoord(lnglat: [number, number]): any { - // @ts-ignore - const { x, y } = this.map.lngLatToGeodeticCoord(lnglat); - return [x, -y]; - } - - public lngLatToMercator( - // eslint-disable-next-line @typescript-eslint/no-unused-vars - lnglat: [number, number], - // eslint-disable-next-line @typescript-eslint/no-unused-vars - altitude: number, - ): IMercator { - return { - x: 0, - y: 0, - z: 0, - }; - } - - public getModelMatrix( - lnglat: [number, number], - altitude: number, - rotate: [number, number, number], - scale: [number, number, number] = [1, 1, 1], - ): number[] { - const flat = this.viewport.projectFlat(lnglat); - // @ts-ignore - const modelMatrix = mat4.create(); - - mat4.translate(modelMatrix, modelMatrix, vec3.fromValues(flat[0], flat[1], altitude)); - mat4.scale(modelMatrix, modelMatrix, vec3.fromValues(scale[0], scale[1], scale[2])); - - mat4.rotateX(modelMatrix, modelMatrix, rotate[0]); - mat4.rotateY(modelMatrix, modelMatrix, rotate[1]); - mat4.rotateZ(modelMatrix, modelMatrix, rotate[2]); - - return modelMatrix as unknown as number[]; - } - - public async init(): Promise { - const { - id, - style = 'light', - minZoom = 0, - maxZoom = 18, - token = AMAP_API_KEY, - mapInstance, - plugin = [], - ...rest - } = this.config; - // 高德地图创建独立的container; - // tslint:disable-next-line:typedef - await new Promise((resolve) => { - const resolveMap = () => { - if (mapInstance) { - this.map = mapInstance as AMap.Map & IAMapInstance; - this.$mapContainer = this.map.getContainer(); - setTimeout(() => { - this.map.on('camerachange', this.handleCameraChanged); - resolve(); - }, 30); - } else { - this.$mapContainer = this.creatMapContainer(id as string | HTMLDivElement); - const mapConstructorOptions = { - mapStyle: this.getMapStyleValue(style as string), - zooms: [minZoom, maxZoom], - viewMode: '3D', - ...rest, - }; - if (mapConstructorOptions.zoom) { - // TODO: 高德地图在相同大小下需要比 MapBox 多一个 zoom 层级 - mapConstructorOptions.zoom += 1; - } - // @ts-ignore - const map = new AMap.Map(this.$mapContainer, mapConstructorOptions); - // 监听地图相机事件 - map.on('camerachange', this.handleCameraChanged); - // Tip: 为了兼容开启 MultiPassRender 的情况 - // 修复 MultiPassRender 在高德地图 1.x 的情况下,缩放地图改变 zoom 时存在可视化层和底图不同步的现象 - map.on('camerachange', () => { - setTimeout(() => this.handleAfterMapChange()); - }); - - // @ts-ignore - this.map = map; - setTimeout(() => { - resolve(); - }, 10); - } - }; - if (!amapLoaded && !mapInstance) { - if (token === AMAP_API_KEY) { - console.warn( - `%c${this.configService.getSceneWarninfo('MapToken')}!`, - 'color: #873bf4;font-weigh:900;font-size: 16px;', - ); - } - amapLoaded = true; - plugin.push('Map3D'); - AMapLoader.load({ - key: token, // 申请好的Web端开发者Key,首次调用 load 时必填 - version: AMAP_VERSION, // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15 - plugins: plugin, // 需要使用的的插件列表,如比例尺'AMap.Scale'等 - }) - .then(() => { - resolveMap(); - - if (pendingResolveQueue.length) { - pendingResolveQueue.forEach((r) => r()); - pendingResolveQueue = []; - } - }) - .catch((e) => { - throw new Error(e); - }); - } else { - if ((amapLoaded && window.AMap) || mapInstance) { - resolveMap(); - } else { - pendingResolveQueue.push(resolveMap); - } - } - }); - - this.viewport = new Viewport(); - } - - public meterToCoord(center: [number, number], outer: [number, number]) { - // 统一根据经纬度来转化 - // Tip: 实际米距离 unit meter - const meterDis = AMap.GeometryUtil.distance( - new AMap.LngLat(...center), - new AMap.LngLat(...outer), - ); - - // Tip: 三维世界坐标距离 - const [x1, y1] = this.lngLatToCoord(center); - const [x2, y2] = this.lngLatToCoord(outer); - const coordDis = Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)); - - return coordDis / meterDis; - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public updateView(viewOption: Partial): void { - return; - } - - public getOverlayContainer(): HTMLElement | undefined { - return undefined; - } - - public exportMap(type: 'jpg' | 'png'): string { - const renderCanvas = this.getContainer()?.getElementsByClassName( - 'amap-layer', - )[0] as HTMLCanvasElement; - const layersPng = - type === 'jpg' - ? (renderCanvas?.toDataURL('image/jpeg') as string) - : (renderCanvas?.toDataURL('image/png') as string); - return layersPng; - } - - public emit(name: string, ...args: any[]) { - this.eventEmitter.emit(name, ...args); - } - - public once(name: string, ...args: any[]) { - this.eventEmitter.once(name, ...args); - } - - public destroy() { - // TODO: 销毁地图可视化层的容器 - this.$mapContainer?.parentNode?.removeChild(this.$mapContainer); - - // @ts-ignore - delete window.initAMap; - const $jsapi = document.getElementById(AMAP_SCRIPT_ID); - if ($jsapi) { - document.head.removeChild($jsapi); - } - this.map.destroy(); - } - - public getMapContainer() { - return this.$mapContainer; - } - - public onCameraChanged(callback: (viewport: IViewport) => void): void { - this.cameraChangedCallback = callback; - } - - protected handleAfterMapChange() { - this.emit('mapAfterFrameChange'); - } - - protected handleCameraChanged = (e: IAMapEvent): void => { - const { fov, near, far, height, pitch, rotation, aspect, position } = e.camera; - const { lng, lat } = this.getCenter(); - // Tip: 触发地图变化事件 - this.emit('mapchange'); - - if (this.cameraChangedCallback) { - // resync viewport - this.viewport.syncWithMapCamera({ - aspect, - // AMap 定义 rotation 为顺时针方向,而 Mapbox 为逆时针 - // @see https://docs.mapbox.com/mapbox-gl-js/api/#map#getbearing - bearing: 360 - rotation, - far, - fov, - cameraHeight: height, - near, - pitch, - // AMap 定义的缩放等级 与 Mapbox 相差 1 - zoom: this.map.getZoom() - 1, - center: [lng, lat], - offsetOrigin: [position.x, position.y], - }); - const { offsetZoom = LNGLAT_OFFSET_ZOOM_THRESHOLD } = this.config; - // set coordinate system - if (this.viewport.getZoom() > offsetZoom) { - this.coordinateSystemService.setCoordinateSystem(CoordinateSystem.P20_OFFSET); - } else { - this.coordinateSystemService.setCoordinateSystem(CoordinateSystem.P20); - } - this.cameraChangedCallback(this.viewport); - } - }; - protected creatMapContainer(id: string | HTMLDivElement) { - let $wrapper = id as HTMLDivElement; - if (typeof id === 'string') { - $wrapper = document.getElementById(id) as HTMLDivElement; - } - const $amapdiv = document.createElement('div'); - $amapdiv.style.cssText += ` - position: absolute; - top: 0; - height: 100%; - width: 100%; - `; - $amapdiv.id = 'l7_amap_div' + mapdivCount++; - $wrapper.appendChild($amapdiv); - return $amapdiv; - } -} diff --git a/packages/maps/src/utils/amap/Viewport.ts b/packages/maps/src/utils/amap/Viewport.ts deleted file mode 100644 index d50a577c7da..00000000000 --- a/packages/maps/src/utils/amap/Viewport.ts +++ /dev/null @@ -1,127 +0,0 @@ -import type { IMapCamera, IViewport } from '@antv/l7-core'; -import { mat4, vec3 } from 'gl-matrix'; - -const DEGREES_TO_RADIANS = Math.PI / 180; - -export default class Viewport implements IViewport { - private projectionMatrix: mat4 = mat4.create(); - private viewMatrix: mat4 = mat4.create(); - private viewProjectionMatrix: mat4 = mat4.create(); - private ViewProjectionMatrixUncentered: mat4 = mat4.create(); - private viewUncenteredMatrix: mat4 = mat4.create(); - private zoom: number; - private center: number[]; - - public syncWithMapCamera(mapCamera: Partial) { - const { - zoom = 1, - pitch = 0, - bearing = 0, - center = [0, 0], - offsetOrigin = [0, 0], - cameraHeight = 1, - aspect = 1, - near = 0.1, - far = 1000, - fov = 0, - } = mapCamera; - this.zoom = zoom; - this.center = center; - - const pitchInRadians = pitch * DEGREES_TO_RADIANS; - const rotationInRadians = (360 - bearing) * DEGREES_TO_RADIANS; - - // 计算透视投影矩阵 projectionMatrix - mat4.perspective(this.projectionMatrix, fov, aspect, near, far); - // 计算相机矩阵 viewMatrix - const eye = vec3.fromValues( - cameraHeight * Math.sin(pitchInRadians) * Math.sin(rotationInRadians), - -cameraHeight * Math.sin(pitchInRadians) * Math.cos(rotationInRadians), - cameraHeight * Math.cos(pitchInRadians), - ); - const up = vec3.fromValues( - -Math.cos(pitchInRadians) * Math.sin(rotationInRadians), - Math.cos(pitchInRadians) * Math.cos(rotationInRadians), - Math.sin(pitchInRadians), - ); - mat4.lookAt(this.viewMatrix, eye, vec3.fromValues(0, 0, 0), up); - this.viewUncenteredMatrix = mat4.clone(this.viewMatrix); - - // 移动相机位置 - mat4.translate( - this.viewMatrix, - this.viewMatrix, - vec3.fromValues(-offsetOrigin[0], offsetOrigin[1], 0), - ); - - mat4.multiply(this.viewProjectionMatrix, this.projectionMatrix, this.viewMatrix); - mat4.multiply(this.ViewProjectionMatrixUncentered, this.projectionMatrix, this.viewMatrix); - } - - public getZoom(): number { - return this.zoom; - } - - public getZoomScale(): number { - // 512 尺寸下的缩放:2 ^ 19 - return 524288; - } - - public getCenter(): [number, number] { - const [lng, lat] = this.center; - return [lng, lat]; - } - - public getProjectionMatrix(): number[] { - // @ts-ignore - return this.projectionMatrix; - } - - public getModelMatrix(): number[] { - return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; - } - - public getViewMatrix(): number[] { - // @ts-ignore - return this.viewMatrix; - } - - public getViewMatrixUncentered(): number[] { - // @ts-ignore - return this.viewUncenteredMatrix; - } - public getViewProjectionMatrix(): number[] { - // @ts-ignore - return this.viewProjectionMatrix; - } - - public getViewProjectionMatrixUncentered(): number[] { - // @ts-ignore - return this.ViewProjectionMatrixUncentered; - } - - public getFocalDistance() { - return 1; - } - - /** - * P20 坐标系,固定 scale - */ - public projectFlat(lngLat: [number, number]): [number, number] { - const maxs = 85.0511287798; - const lat = Math.max(Math.min(maxs, lngLat[1]), -maxs); - // tslint:disable-next-line:no-bitwise - const zoomScale = 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; - const b = 0.5; - const c = -0.5 / Math.PI; - d = 0.5; - x = zoomScale * (a * x + b) - 215440491; - y = -(zoomScale * (c * y + d) - 106744817); - return [x, y]; - } -} diff --git a/packages/maps/src/utils/amap/logo.css b/packages/maps/src/utils/amap/logo.css deleted file mode 100644 index a5e4fd0de88..00000000000 --- a/packages/maps/src/utils/amap/logo.css +++ /dev/null @@ -1,6 +0,0 @@ -.amap-logo { - display: none !important; -} -.amap-copyright { - display: none !important; -} diff --git a/packages/maps/src/utils/amaploader.ts b/packages/maps/src/utils/amaploader.ts deleted file mode 100644 index 69410ff08d3..00000000000 --- a/packages/maps/src/utils/amaploader.ts +++ /dev/null @@ -1,169 +0,0 @@ -if (!window) { - throw Error('AMap JSAPI can only be used in Browser.'); -} -enum LoadStatus { - notload = 'notload', - loading = 'loading', - loaded = 'loaded', - failed = 'failed', -} -interface IConfig { - key: string; - AMap: { - version: string; - plugins: string[]; - }; -} -let config: IConfig = { - key: '', - AMap: { - version: '2.0', - plugins: [], - }, -}; - -let Status = { - AMap: LoadStatus.notload, -}; - -const onloadCBKs: any[] = []; -// @ts-ignore -const onload = (callback: (map: window.AMap) => void) => { - if (typeof callback === 'function') { - if (Status.AMap === LoadStatus.loaded) { - callback(window.AMap); - return; - } - onloadCBKs.push(callback); - } -}; - -interface ILoadOption { - key: string; - version?: string; - plugins?: string[]; - AMapUI?: { - version?: string; - plugins?: string[]; - }; - Loca?: { - version?: string; - }; -} - -const load = async (options: ILoadOption) => { - return new Promise((resolve, reject) => { - if (Status.AMap === LoadStatus.failed) { - reject(''); - } else if (Status.AMap === LoadStatus.notload) { - // 初次加载 - const { key, version, plugins } = options; - if (!key) { - reject('请填写key'); - return; - } - if (window.AMap && location.host !== 'lbs.amap.com') { - reject('禁止多种API加载方式混用'); - } - config.key = key; - config.AMap.version = version || config.AMap.version; - config.AMap.plugins = plugins || config.AMap.plugins; - Status.AMap = LoadStatus.loading; - - const parentNode = document.body || document.head; - // @ts-ignore - window._onAPILoaded = (err) => { - // @ts-ignore - if (err) { - Status.AMap = LoadStatus.failed; - reject(err); - } else { - Status.AMap = LoadStatus.loaded; - resolve(null); - } - }; - const script = document.createElement('script'); - script.type = 'text/javascript'; - script.async = false; - script.src = - 'https://webapi.amap.com/maps?callback=_onAPILoaded&v=' + - config.AMap.version + - '&key=' + - key + - '&plugin=' + - config.AMap.plugins.join(','); - script.onerror = (e) => { - Status.AMap = LoadStatus.failed; - reject(e); - }; - - parentNode.appendChild(script); - } else if (Status.AMap === LoadStatus.loaded) { - // deal multi load - if (options.key && options.key !== config.key) { - reject('多个不一致的 key'); - return; - } - if (options.version && options.version !== config.AMap.version) { - reject('不允许多个版本 JSAPI 混用'); - return; - } - const newPlugins: string[] = []; - if (options.plugins) { - // @ts-ignore - options.plugins.forEach((p: string) => { - if (config.AMap.plugins.indexOf(p) === -1) { - newPlugins.push(p); - } - }); - } - - if (newPlugins.length) { - window.AMap.plugin(newPlugins, () => { - resolve(window.AMap); - }); - } - } else { - // loading - if (options.key && options.key !== config.key) { - reject('多个不一致的 key'); - return; - } - if (options.version && options.version !== config.AMap.version) { - reject('不允许多个版本 JSAPI 混用'); - return; - } - const newPlugins: string[] = []; - if (options.plugins) { - // @ts-ignore - options.plugins.forEach((p: string) => { - if (config.AMap.plugins.indexOf(p) === -1) { - newPlugins.push(p); - } - }); - } - onload(() => { - if (newPlugins.length) { - window.AMap.plugin(newPlugins, () => { - resolve(window.AMap); - }); - } - }); - } - }); -}; -function reset() { - // @ts-ignore - delete window.AMap; - config = { - key: '', - AMap: { - version: '1.4.15', - plugins: [], - }, - }; - Status = { - AMap: LoadStatus.notload, - }; -} -export default { load, reset }; diff --git a/packages/maps/src/utils/index.ts b/packages/maps/src/utils/index.ts index 13fce12041f..e720907740d 100644 --- a/packages/maps/src/utils/index.ts +++ b/packages/maps/src/utils/index.ts @@ -1,4 +1,3 @@ import BaseMapService from './BaseMapService'; import BaseMapWrapper from './BaseMapWrapper'; -import Viewport from './Viewport'; -export { BaseMapService, BaseMapWrapper, Viewport }; +export { BaseMapService, BaseMapWrapper }; diff --git a/packages/renderer/CHANGELOG.md b/packages/renderer/CHANGELOG.md index e3227815326..06746bab528 100644 --- a/packages/renderer/CHANGELOG.md +++ b/packages/renderer/CHANGELOG.md @@ -1,5 +1,73 @@ # Change Log +## 2.21.11-beta.7 + +### Patch Changes + +- [#2526](https://github.com/antvis/L7/pull/2526) [`3aa0f32`](https://github.com/antvis/L7/commit/3aa0f32b41ef10efa2e9bab46d695bc87ab950f6) Thanks [@lvisei](https://github.com/lvisei)! - fix: 修复 bindings 缓存在 WebGPU 的问题 + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.7 + - @antv/l7-utils@2.21.11-beta.7 + +## 2.21.11-beta.6 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.6 + - @antv/l7-utils@2.21.11-beta.6 + +## 2.21.11-beta.5 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.5 + - @antv/l7-utils@2.21.11-beta.5 + +## 2.21.11-beta.4 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.4 + - @antv/l7-utils@2.21.11-beta.4 + +## 2.21.11-beta.3 + +### Patch Changes + +- Updated dependencies [[`a5f57ed`](https://github.com/antvis/L7/commit/a5f57eda52dab160fe076f252ad52cd51b8f456a)]: + - @antv/l7-core@2.21.11-beta.3 + - @antv/l7-utils@2.21.11-beta.3 + +## 2.21.11-beta.2 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.2 + - @antv/l7-utils@2.21.11-beta.2 + +## 2.21.11-beta.1 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.1 + - @antv/l7-utils@2.21.11-beta.1 + +## 2.21.11-beta.0 + +### Patch Changes + +- [#2473](https://github.com/antvis/L7/pull/2473) [`8b72df1`](https://github.com/antvis/L7/commit/8b72df14dc18ba85f66f8e4e09ba9d80d0379ed3) Thanks [@lvisei](https://github.com/lvisei)! - fix: use stencil.func.ref for each pipeline + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.0 + - @antv/l7-utils@2.21.11-beta.0 + ## 2.21.10 ### Patch Changes diff --git a/packages/renderer/__tests__/index.spec.ts b/packages/renderer/__tests__/index.spec.ts new file mode 100644 index 00000000000..595868f8922 --- /dev/null +++ b/packages/renderer/__tests__/index.spec.ts @@ -0,0 +1,7 @@ +import { DeviceRendererService } from '../src/index'; + +describe('template', () => { + it('DeviceRenderer', () => { + new DeviceRendererService(); + }); +}); diff --git a/packages/renderer/__tests__/regl/attribute.spec.ts b/packages/renderer/__tests__/regl/attribute.spec.ts deleted file mode 100644 index b426fefec3e..00000000000 --- a/packages/renderer/__tests__/regl/attribute.spec.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { gl } from '@antv/l7-core'; -import { glContext } from '@antv/l7-test-utils'; -import regl from 'regl'; -import quad from '../../../core/src/shaders/post-processing/quad.glsl'; -import ReglAttribute from '../../src/regl/ReglAttribute'; -import ReglBuffer from '../../src/regl/ReglBuffer'; -import ReglModel from '../../src/regl/ReglModel'; -import checkPixels from './utils/check-pixels'; - -describe('ReglAttribute', () => { - let reGL: regl.Regl; - - beforeEach(() => { - reGL = regl(glContext); - }); - - it('should initialize without `size`', () => { - const attribute = new ReglAttribute(reGL, { - buffer: new ReglBuffer(reGL, { - data: [ - [-4, -4], - [4, -4], - [0, 4], - ], - type: gl.FLOAT, - }), - }); - const model = new ReglModel(reGL, { - vs: quad, - fs: 'void main() {gl_FragColor = vec4(1., 0., 0., 1.);}', - attributes: { - a_Position: attribute, - }, - depth: { - enable: false, - }, - count: 3, - }); - - reGL.clear({ - color: [0, 0, 0, 0], - }); - - attribute.updateBuffer({ - data: [-4, -4, 4, -4, 0, 4], - offset: 0, - }); - - model.draw({}); - - attribute.destroy(); - - expect(checkPixels(reGL, [255])).toBeTruthy(); - }); - - it('should update buffer correctly', () => { - const attribute = new ReglAttribute(reGL, { - buffer: new ReglBuffer(reGL, { - data: [-4, -4, 4, -4, 0, 4], - type: gl.FLOAT, - }), - size: 2, - }); - const model = new ReglModel(reGL, { - vs: quad, - fs: 'void main() {gl_FragColor = vec4(1., 0., 0., 1.);}', - attributes: { - a_Position: attribute, - }, - depth: { - enable: false, - }, - count: 3, - }); - - reGL.clear({ - color: [0, 0, 0, 0], - }); - - attribute.updateBuffer({ - data: [-4, -4, 4, -4, 0, 4], - offset: 0, - }); - - model.draw({}); - - attribute.destroy(); - - expect(checkPixels(reGL, [255])).toBeTruthy(); - }); -}); diff --git a/packages/renderer/__tests__/regl/elements.spec.ts b/packages/renderer/__tests__/regl/elements.spec.ts deleted file mode 100644 index e0caa1d963f..00000000000 --- a/packages/renderer/__tests__/regl/elements.spec.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { gl } from '@antv/l7-core'; - -import { glContext } from '@antv/l7-test-utils'; -import regl from 'regl'; -import quad from '../../../core/src/shaders/post-processing/quad.glsl'; -import ReglAttribute from '../../src/regl/ReglAttribute'; -import ReglBuffer from '../../src/regl/ReglBuffer'; -import ReglElements from '../../src/regl/ReglElements'; -import ReglModel from '../../src/regl/ReglModel'; -import checkPixels from './utils/check-pixels'; - -describe('ReglElements', () => { - let reGL: regl.Regl; - - beforeEach(() => { - reGL = regl(glContext); - }); - - it('should initialize correctly', () => { - const model = new ReglModel(reGL, { - vs: quad, - fs: 'void main() {gl_FragColor = vec4(1., 0., 0., 1.);}', - attributes: { - a_Position: new ReglAttribute(reGL, { - buffer: new ReglBuffer(reGL, { - data: [-4, -4, 4, -4, 0, 4], - type: gl.FLOAT, - }), - size: 2, - }), - }, - depth: { - enable: false, - }, - elements: new ReglElements(reGL, { - data: [0, 1, 2], - count: 3, - }), - }); - - reGL.clear({ - color: [0, 0, 0, 0], - }); - - model.draw({}); - - expect(checkPixels(reGL, [255])).toBeTruthy(); - }); - - it('should update correctly', () => { - const elements = new ReglElements(reGL, { - data: [0, 1, 2], - count: 3, - }); - const model = new ReglModel(reGL, { - vs: quad, - fs: 'void main() {gl_FragColor = vec4(1., 0., 0., 1.);}', - attributes: { - a_Position: new ReglAttribute(reGL, { - buffer: new ReglBuffer(reGL, { - data: [-4, -4, 4, -4, 0, 4], - type: gl.FLOAT, - }), - size: 2, - }), - }, - depth: { - enable: false, - }, - elements, - }); - - reGL.clear({ - color: [0, 0, 0, 0], - }); - - elements.subData({ - data: [0, 1, 2], - }); - - model.draw({}); - - elements.destroy(); - - expect(checkPixels(reGL, [255])).toBeTruthy(); - }); -}); diff --git a/packages/renderer/__tests__/regl/framebuffer.spec.ts b/packages/renderer/__tests__/regl/framebuffer.spec.ts deleted file mode 100644 index a1206b414c6..00000000000 --- a/packages/renderer/__tests__/regl/framebuffer.spec.ts +++ /dev/null @@ -1,188 +0,0 @@ -import { gl } from '@antv/l7-core'; - -import { glContext } from '@antv/l7-test-utils'; -import regl from 'regl'; -import quad from '../../../core/src/shaders/post-processing/quad.glsl'; -import ReglAttribute from '../../src/regl/ReglAttribute'; -import ReglBuffer from '../../src/regl/ReglBuffer'; -import ReglElements from '../../src/regl/ReglElements'; -import ReglFramebuffer from '../../src/regl/ReglFramebuffer'; -import ReglModel from '../../src/regl/ReglModel'; -import ReglRenderbuffer from '../../src/regl/ReglRenderbuffer'; -import ReglTexture2D from '../../src/regl/ReglTexture2D'; -import checkPixels from './utils/check-pixels'; - -describe('ReglFramebuffer', () => { - let reGL: regl.Regl; - - beforeEach(() => { - reGL = regl(glContext); - }); - - it('should initialize correctly', () => { - const model = new ReglModel(reGL, { - vs: quad, - fs: 'void main() {gl_FragColor = vec4(1., 0., 0., 1.);}', - attributes: { - a_Position: new ReglAttribute(reGL, { - buffer: new ReglBuffer(reGL, { - data: [-4, -4, 4, -4, 0, 4], - type: gl.FLOAT, - }), - size: 2, - }), - }, - depth: { - enable: false, - }, - elements: new ReglElements(reGL, { - data: [0, 1, 2], - count: 3, - }), - }); - const framebuffer = new ReglFramebuffer(reGL, { - color: new ReglTexture2D(reGL, { - width: 1, - height: 1, - }), - }); - - reGL({ framebuffer: framebuffer.get() })(() => { - reGL.clear({ - color: [0, 0, 0, 0], - }); - model.draw({}); - expect(checkPixels(reGL, [255])).toBeTruthy(); - }); - }); - - it('should initialize with colors correctly', () => { - const model = new ReglModel(reGL, { - vs: quad, - fs: 'void main() {gl_FragColor = vec4(1., 0., 0., 1.);}', - attributes: { - a_Position: new ReglAttribute(reGL, { - buffer: new ReglBuffer(reGL, { - data: [-4, -4, 4, -4, 0, 4], - type: gl.FLOAT, - }), - size: 2, - }), - }, - depth: { - enable: false, - }, - elements: new ReglElements(reGL, { - data: [0, 1, 2], - count: 3, - }), - }); - const framebuffer = new ReglFramebuffer(reGL, { - colors: [ - new ReglTexture2D(reGL, { - width: 1, - height: 1, - }), - ], - }); - - reGL({ framebuffer: framebuffer.get() })(() => { - reGL.clear({ - color: [0, 0, 0, 0], - }); - model.draw({}); - expect(checkPixels(reGL, [255])).toBeTruthy(); - }); - }); - - it('should resize correctly', () => { - const model = new ReglModel(reGL, { - vs: quad, - fs: 'void main() {gl_FragColor = vec4(1., 0., 0., 1.);}', - attributes: { - a_Position: new ReglAttribute(reGL, { - buffer: new ReglBuffer(reGL, { - data: [-4, -4, 4, -4, 0, 4], - type: gl.FLOAT, - }), - size: 2, - }), - }, - depth: { - enable: false, - }, - elements: new ReglElements(reGL, { - data: [0, 1, 2], - count: 3, - }), - }); - const framebuffer = new ReglFramebuffer(reGL, { - color: new ReglTexture2D(reGL, { - width: 1, - height: 1, - }), - }); - - framebuffer.resize({ - width: 1, - height: 1, - }); - - reGL({ framebuffer: framebuffer.get() })(() => { - reGL.clear({ - color: [0, 0, 0, 0], - }); - model.draw({}); - expect(checkPixels(reGL, [255])).toBeTruthy(); - }); - - framebuffer.destroy(); - }); - - it('should initialize with renderbuffer correctly', () => { - const model = new ReglModel(reGL, { - vs: quad, - fs: 'void main() {gl_FragColor = vec4(1., 0., 0., 1.);}', - attributes: { - a_Position: new ReglAttribute(reGL, { - buffer: new ReglBuffer(reGL, { - data: [-4, -4, 4, -4, 0, 4], - type: gl.FLOAT, - }), - size: 2, - }), - }, - depth: { - enable: false, - }, - elements: new ReglElements(reGL, { - data: [0, 1, 2], - count: 3, - }), - }); - - const renderbuffer = new ReglRenderbuffer(reGL, { - width: 1, - height: 1, - format: gl.RGBA4, - }); - const framebuffer = new ReglFramebuffer(reGL, { - color: renderbuffer, - }); - - renderbuffer.resize({ - width: 1, - height: 1, - }); - - reGL({ framebuffer: framebuffer.get() })(() => { - reGL.clear({ - color: [0, 0, 0, 0], - }); - model.draw({}); - }); - - framebuffer.destroy(); - renderbuffer.destroy(); - }); -}); diff --git a/packages/renderer/__tests__/regl/model.draw.spec.ts b/packages/renderer/__tests__/regl/model.draw.spec.ts deleted file mode 100644 index 18b98543ea0..00000000000 --- a/packages/renderer/__tests__/regl/model.draw.spec.ts +++ /dev/null @@ -1,155 +0,0 @@ -import { gl } from '@antv/l7-core'; - -import { glContext } from '@antv/l7-test-utils'; -import regl from 'regl'; -import quad from '../../../core/src/shaders/post-processing/quad.glsl'; -import ReglAttribute from '../../src/regl/ReglAttribute'; -import ReglBuffer from '../../src/regl/ReglBuffer'; -import ReglModel from '../../src/regl/ReglModel'; -import checkPixels from './utils/check-pixels'; -import globalDefaultprecision from './utils/default-precision'; - -describe('Initialization for ReglModel', () => { - let reGL: regl.Regl; - - beforeEach(() => { - reGL = regl(glContext); - }); - - it('should draw a red quad', () => { - const model = new ReglModel(reGL, { - vs: quad, - fs: 'void main() {gl_FragColor = vec4(1., 0., 0., 1.);}', - attributes: { - a_Position: new ReglAttribute(reGL, { - buffer: new ReglBuffer(reGL, { - data: [-4, -4, 4, -4, 0, 4], - type: gl.FLOAT, - }), - size: 2, - }), - }, - depth: { - enable: false, - }, - stencil: { - enable: false, - }, - blend: { - enable: false, - }, - primitive: gl.TRIANGLES, - count: 3, - }); - - reGL.clear({ - color: [0, 0, 0, 0], - }); - - model.draw({}); - - expect(checkPixels(reGL, [255])).toBeTruthy(); - }); - - it('should cull front face', () => { - const model = new ReglModel(reGL, { - vs: quad, - fs: 'void main() {gl_FragColor = vec4(1., 0., 0., 1.);}', - attributes: { - a_Position: new ReglAttribute(reGL, { - buffer: new ReglBuffer(reGL, { - data: [-4, -4, 4, -4, 0, 4], - type: gl.FLOAT, - }), - size: 2, - }), - }, - depth: { - enable: false, - }, - count: 3, - cull: { - enable: true, - face: gl.FRONT, - }, - }); - - reGL.clear({ - color: [0, 0, 0, 0], - }); - - model.draw({}); - - expect(checkPixels(reGL, [0])).toBeTruthy(); - }); - - it('should draw with instances', () => { - const model = new ReglModel(reGL, { - vs: quad, - fs: 'void main() {gl_FragColor = vec4(1., 0., 0., 1.);}', - attributes: { - a_Position: new ReglAttribute(reGL, { - buffer: new ReglBuffer(reGL, { - data: [-4, -4, 4, -4, 0, 4], - type: gl.FLOAT, - }), - size: 2, - }), - }, - depth: { - enable: false, - }, - count: 3, - instances: 1, - }); - - reGL.clear({ - color: [0, 0, 0, 0], - }); - - model.draw({}); - - expect(checkPixels(reGL, [255])).toBeTruthy(); - }); - - it('should draw with uniforms', () => { - const model = new ReglModel(reGL, { - vs: quad, - fs: ` - ${globalDefaultprecision} - uniform vec4 u_Color; - void main() { - gl_FragColor = u_Color; - } - `, - attributes: { - a_Position: new ReglAttribute(reGL, { - buffer: new ReglBuffer(reGL, { - data: [-4, -4, 4, -4, 0, 4], - type: gl.FLOAT, - }), - size: 2, - }), - }, - uniforms: { - u_Color: [0, 0, 0, 0], - }, - depth: { - enable: false, - }, - count: 3, - }); - - reGL.clear({ - color: [0, 0, 0, 0], - }); - - model.draw({ - uniforms: { - u_Color: [1, 0, 0, 1], - }, - }); - - expect(checkPixels(reGL, [255])).toBeTruthy(); - }); -}); diff --git a/packages/renderer/__tests__/regl/model.spec.ts b/packages/renderer/__tests__/regl/model.spec.ts deleted file mode 100644 index f5da935fa08..00000000000 --- a/packages/renderer/__tests__/regl/model.spec.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { glContext } from '@antv/l7-test-utils'; -import regl from 'regl'; -import ReglModel from '../../src/regl/ReglModel'; - -describe('ReglModel', () => { - let reGL: regl.Regl; - - beforeEach(() => { - reGL = regl(glContext); - }); - - it('should generate model with empty uniforms correctly', () => { - const model = new ReglModel(reGL, { - vs: 'void main() {gl_Position = vec4(0.);}', - fs: 'void main() {gl_FragColor = vec4(0.);}', - attributes: {}, - }); - - // @ts-ignore - expect(model.uniforms).toEqual({}); - }); - - it('should generate model with uniforms correctly', () => { - const model = new ReglModel(reGL, { - vs: 'void main() {gl_Position = vec4(0.);}', - fs: 'void main() {gl_FragColor = vec4(0.);}', - attributes: {}, - uniforms: { - u_1: 1, - u_2: [1, 2], - }, - }); - - // @ts-ignore - expect(model.uniforms.u_1).toEqual(1); - // @ts-ignore - expect(model.uniforms.u_2).toEqual([1, 2]); - }); - - it('should generate model with struct uniforms correctly', () => { - // 支持 struct 结构,例如 'colors[0].r' - // @see https://github.com/regl-project/regl/blob/gh-pages/API.md#uniforms - const model = new ReglModel(reGL, { - vs: 'void main() {gl_Position = vec4(0.);}', - fs: 'void main() {gl_FragColor = vec4(0.);}', - attributes: {}, - // @ts-ignore - uniforms: { - // @ts-ignore - u_Struct: [ - { - a: 1, - b: [1, 2], - }, - { - a: 2, - b: [3, 4], - }, - ], - }, - }); - - // @ts-ignore - expect(model.uniforms['u_Struct[0].a']).toEqual(1); - // @ts-ignore - expect(model.uniforms['u_Struct[0].b']).toEqual([1, 2]); - // @ts-ignore - expect(model.uniforms['u_Struct[1].a']).toEqual(2); - // @ts-ignore - expect(model.uniforms['u_Struct[1].b']).toEqual([3, 4]); - }); -}); diff --git a/packages/renderer/__tests__/regl/model.uniform.spec.ts b/packages/renderer/__tests__/regl/model.uniform.spec.ts deleted file mode 100644 index 69b94b9fba0..00000000000 --- a/packages/renderer/__tests__/regl/model.uniform.spec.ts +++ /dev/null @@ -1,207 +0,0 @@ -import { glContext } from '@antv/l7-test-utils'; -import regl from 'regl'; -import ReglFramebuffer from '../../src/regl/ReglFramebuffer'; -import ReglModel from '../../src/regl/ReglModel'; -import ReglTexture2D from '../../src/regl/ReglTexture2D'; - -describe('uniforms in ReglModel', () => { - let reGL: regl.Regl; - - beforeEach(() => { - reGL = regl(glContext); - }); - - it('should generate model with empty uniforms correctly', () => { - const model = new ReglModel(reGL, { - vs: 'void main() {gl_Position = vec4(0.);}', - fs: 'void main() {gl_FragColor = vec4(0.);}', - attributes: {}, - }); - - // @ts-ignore - expect(model.uniforms).toEqual({}); - }); - - it('should generate model with uniforms correctly', () => { - const model = new ReglModel(reGL, { - vs: 'void main() {gl_Position = vec4(0.);}', - fs: 'void main() {gl_FragColor = vec4(0.);}', - attributes: {}, - uniforms: { - u_1: 1, - u_2: [1, 2], - u_3: false, - u_4: new Float32Array([1, 2, 3]), - }, - }); - - // @ts-ignore - expect(model.uniforms.u_1).toEqual(1); - // @ts-ignore - expect(model.uniforms.u_2).toEqual([1, 2]); - // @ts-ignore - expect(model.uniforms.u_3).toEqual(false); - // @ts-ignore - expect(model.uniforms.u_4).toEqual(new Float32Array([1, 2, 3])); - }); - - it('should generate model with struct uniforms correctly', () => { - // 支持 struct 结构,例如 'colors[0].r' - // @see https://github.com/regl-project/regl/blob/gh-pages/API.md#uniforms - const model = new ReglModel(reGL, { - vs: 'void main() {gl_Position = vec4(0.);}', - fs: 'void main() {gl_FragColor = vec4(0.);}', - attributes: {}, - // @ts-ignore - uniforms: { - // @ts-ignore - u_Struct: [ - { - a: 1, - b: [1, 2], - }, - { - a: 2, - b: [3, 4], - }, - ], - }, - }); - - // @ts-ignore - expect(model.uniforms['u_Struct[0].a']).toEqual(1); - // @ts-ignore - expect(model.uniforms['u_Struct[0].b']).toEqual([1, 2]); - // @ts-ignore - expect(model.uniforms['u_Struct[1].a']).toEqual(2); - // @ts-ignore - expect(model.uniforms['u_Struct[1].b']).toEqual([3, 4]); - - // 测试结构体嵌套的场景 - const model2 = new ReglModel(reGL, { - vs: 'void main() {gl_Position = vec4(0.);}', - fs: 'void main() {gl_FragColor = vec4(0.);}', - attributes: {}, - // @ts-ignore - uniforms: { - // @ts-ignore - u_Struct: { - a: 1, - b: [1, 2], - c: { - d: 2, - e: [3, 4], - }, - f: false, - g: [ - { - h: 3, - i: [ - { - j: 4, - }, - ], - }, - ], - k: new ReglTexture2D(reGL, { - width: 1, - height: 1, - }), - l: new ReglFramebuffer(reGL, { - width: 1, - height: 1, - }), - m: null, - }, - }, - }); - - // @ts-ignore - expect(model2.uniforms['u_Struct.a']).toEqual(1); - // @ts-ignore - expect(model2.uniforms['u_Struct.b']).toEqual([1, 2]); - // @ts-ignore - expect(model2.uniforms['u_Struct.c.d']).toEqual(2); - // @ts-ignore - expect(model2.uniforms['u_Struct.c.e']).toEqual([3, 4]); - // @ts-ignore - expect(model2.uniforms['u_Struct.f']).toEqual(false); - // @ts-ignore - expect(model2.uniforms['u_Struct.g[0].h']).toEqual(3); - // @ts-ignore - expect(model2.uniforms['u_Struct.g[0].i[0].j']).toEqual(4); - // @ts-ignore - expect(model2.uniforms['u_Struct.k'] instanceof ReglTexture2D).toBeTruthy(); - // @ts-ignore - expect( - // @ts-ignore - model2.uniforms['u_Struct.l'] instanceof ReglFramebuffer, - ).toBeTruthy(); - // @ts-ignore - expect(model2.uniforms['u_Struct.m']).toBeNull(); - }); - - it('should update uniforms correctly', () => { - const model = new ReglModel(reGL, { - vs: 'void main() {gl_Position = vec4(0.);}', - fs: 'void main() {gl_FragColor = vec4(0.);}', - attributes: {}, - // @ts-ignore - uniforms: { - u_1: 1, - u_2: [1, 2], - u_3: false, - u_4: { - a: 1, - b: 2, - }, - // @ts-ignore - u_5: [ - { - c: 1, - }, - { - c: 2, - }, - { - c: 3, - }, - ], - }, - }); - - model.addUniforms({ - u_1: 2, - u_2: [3, 4], - u_3: true, - u_4: { - a: 2, - }, - // @ts-ignore - u_5: [ - // @ts-ignore - { - c: 100, // 只修改第一个 - }, - ], - 'u_5[2].c': 200, // 直接修改结构体属性 - }); - - // @ts-ignore - expect(model.uniforms.u_1).toEqual(2); - // @ts-ignore - expect(model.uniforms.u_2).toEqual([3, 4]); - // @ts-ignore - expect(model.uniforms.u_3).toBeTruthy(); - // @ts-ignore - expect(model.uniforms['u_4.a']).toEqual(2); - // @ts-ignore - expect(model.uniforms['u_4.b']).toEqual(2); - // @ts-ignore - expect(model.uniforms['u_5[0].c']).toEqual(100); - // @ts-ignore - expect(model.uniforms['u_5[1].c']).toEqual(2); - // @ts-ignore - expect(model.uniforms['u_5[2].c']).toEqual(200); - }); -}); diff --git a/packages/renderer/__tests__/regl/renderer.spec.ts b/packages/renderer/__tests__/regl/renderer.spec.ts deleted file mode 100644 index d97f31d4fb6..00000000000 --- a/packages/renderer/__tests__/regl/renderer.spec.ts +++ /dev/null @@ -1,271 +0,0 @@ -import { gl } from '@antv/l7-core'; - -import { glContext } from '@antv/l7-test-utils'; -import regl from 'regl'; -import copy from '../../../core/src/shaders/post-processing/copy.glsl'; -import quad from '../../../core/src/shaders/post-processing/quad.glsl'; -import { ReglRendererService } from '../../src/index'; -import ReglAttribute from '../../src/regl/ReglAttribute'; -import ReglBuffer from '../../src/regl/ReglBuffer'; -import checkPixels from './utils/check-pixels'; -import globalDefaultprecision from './utils/default-precision'; - -describe('ReglRendererService', () => { - let reGL: regl.Regl; - const rendererService = new ReglRendererService(); - - beforeEach(() => { - reGL = regl(glContext); - // @ts-ignore - rendererService.gl = reGL; - }); - - it('should getViewportSize correctly after setViewport', () => { - const { viewport, getViewportSize } = rendererService; - const { width, height } = getViewportSize(); - expect(width).toEqual(1); - expect(height).toEqual(1); - - viewport({ - x: 0, - y: 0, - width: 1, - height: 1, - }); - - expect(width).toEqual(1); - expect(height).toEqual(1); - }); - - it('should create model with createModel API', () => { - const { clear, createModel, createAttribute, createBuffer } = rendererService; - const model = createModel({ - vs: quad, - fs: 'void main() {gl_FragColor = vec4(1., 0., 0., 1.);}', - attributes: { - a_Position: createAttribute({ - buffer: createBuffer({ - data: [ - [-4, -4], - [4, -4], - [0, 4], - ], - type: gl.FLOAT, - }), - }), - }, - depth: { - enable: false, - }, - count: 3, - }); - - clear({ - color: [0, 0, 0, 0], - }); - - model.draw({}); - - expect(checkPixels(reGL, [255])).toBeTruthy(); - }); - - it('should draw with createElements', () => { - const { clear, createModel, createAttribute, createBuffer, createElements } = rendererService; - const model = createModel({ - vs: quad, - fs: 'void main() {gl_FragColor = vec4(1., 0., 0., 1.);}', - attributes: { - a_Position: createAttribute({ - buffer: createBuffer({ - data: [ - [-4, -4], - [4, -4], - [0, 4], - ], - type: gl.FLOAT, - }), - }), - }, - depth: { - enable: false, - }, - elements: createElements({ - data: [0, 1, 2], - count: 3, - }), - }); - - clear({ - color: [0, 0, 0, 0], - }); - - model.draw({}); - - expect(checkPixels(reGL, [255])).toBeTruthy(); - }); - - it('should render to framebuffer with `useFramebuffer` correctly', () => { - const { clear, createModel, createAttribute, createBuffer, createFramebuffer, useFramebuffer } = - rendererService; - const model = createModel({ - vs: quad, - fs: 'void main() {gl_FragColor = vec4(1., 0., 0., 1.);}', - attributes: { - a_Position: createAttribute({ - buffer: createBuffer({ - data: [ - [-4, -4], - [4, -4], - [0, 4], - ], - type: gl.FLOAT, - }), - }), - }, - depth: { - enable: false, - }, - count: 3, - }); - const framebuffer = createFramebuffer({ - width: 1, - height: 1, - }); - - useFramebuffer(framebuffer, () => { - clear({ - color: [0, 0, 0, 0], - framebuffer, - }); - model.draw({}); - expect(checkPixels(reGL, [255])).toBeTruthy(); - }); - - // render to screen - useFramebuffer(null, () => { - clear({ - color: [0, 0, 0, 0], - }); - model.draw({}); - expect(checkPixels(reGL, [255])).toBeTruthy(); - }); - }); - - it('should readPixels correctly', () => { - const { - clear, - createModel, - createAttribute, - createBuffer, - createFramebuffer, - useFramebuffer, - readPixels, - destroy, - } = rendererService; - const model = createModel({ - vs: quad, - fs: 'void main() {gl_FragColor = vec4(1., 0., 0., 1.);}', - attributes: { - a_Position: createAttribute({ - buffer: createBuffer({ - data: [ - [-4, -4], - [4, -4], - [0, 4], - ], - type: gl.FLOAT, - }), - }), - }, - depth: { - enable: false, - }, - count: 3, - }); - const framebuffer = createFramebuffer({ - width: 1, - height: 1, - }); - - useFramebuffer(framebuffer, async () => { - clear({ - color: [0, 0, 0, 0], - framebuffer, - }); - model.draw({}); - - const pixels = await readPixels({ - x: 0, - y: 0, - width: 1, - height: 1, - framebuffer, - }); - expect(pixels[0]).toBe(255); - }); - - // render to screen - useFramebuffer(null, async () => { - clear({ - color: [0, 0, 0, 0], - }); - model.draw({}); - const pixels = await readPixels({ - x: 0, - y: 0, - width: 1, - height: 1, - framebuffer: undefined, - }); - expect(pixels[0]).toBe(255); - }); - - destroy(); - }); - - it('should render a fullscreen texture', () => { - const { createModel, createTexture2D } = rendererService; - const model = createModel({ - vs: quad, - fs: globalDefaultprecision + copy, - attributes: { - a_Position: new ReglAttribute(reGL, { - buffer: new ReglBuffer(reGL, { - data: [ - [-4, -4], - [4, -4], - [0, 4], - ], - type: gl.FLOAT, - }), - }), - }, - uniforms: { - // 创建一个红色的纹理 - u_Texture: createTexture2D({ - width: 1, - height: 1, - data: [255, 0, 0, 255], - }), - }, - depth: { - enable: false, - }, - count: 3, - }); - - reGL.clear({ - color: [0, 0, 0, 0], - }); - - model.draw({}); - - // 全屏应该都是红色 - expect(checkPixels(reGL, [255])).toBeTruthy(); - }); - - it('should getContainer correctly', () => { - const { getContainer } = rendererService; - expect(getContainer()).toBeUndefined(); - }); -}); diff --git a/packages/renderer/__tests__/regl/texture.spec.ts b/packages/renderer/__tests__/regl/texture.spec.ts deleted file mode 100644 index e064ca1a0aa..00000000000 --- a/packages/renderer/__tests__/regl/texture.spec.ts +++ /dev/null @@ -1,206 +0,0 @@ -import { gl } from '@antv/l7-core'; - -import { glContext } from '@antv/l7-test-utils'; -import regl from 'regl'; -import copy from '../../../core/src/shaders/post-processing/copy.glsl'; -import quad from '../../../core/src/shaders/post-processing/quad.glsl'; -import ReglAttribute from '../../src/regl/ReglAttribute'; -import ReglBuffer from '../../src/regl/ReglBuffer'; -import ReglModel from '../../src/regl/ReglModel'; -import ReglTexture2D from '../../src/regl/ReglTexture2D'; -import checkPixels from './utils/check-pixels'; -import globalDefaultprecision from './utils/default-precision'; - -describe('ReglTexture', () => { - let reGL: regl.Regl; - - beforeEach(() => { - reGL = regl(glContext); - }); - - it('should initialize with `data`', () => { - const model = new ReglModel(reGL, { - vs: quad, - fs: globalDefaultprecision + copy, - attributes: { - a_Position: new ReglAttribute(reGL, { - buffer: new ReglBuffer(reGL, { - data: [ - [-4, -4], - [4, -4], - [0, 4], - ], - type: gl.FLOAT, - }), - }), - }, - uniforms: { - // 创建一个红色的纹理 - u_Texture: new ReglTexture2D(reGL, { - width: 1, - height: 1, - data: [255, 0, 0, 255], - }), - }, - depth: { - enable: false, - }, - count: 3, - }); - - reGL.clear({ - color: [0, 0, 0, 0], - }); - - model.draw({}); - - // 全屏应该都是红色 - expect(checkPixels(reGL, [255])).toBeTruthy(); - }); - - it('should resize texture', () => { - const texture = new ReglTexture2D(reGL, { - width: 1, - height: 1, - data: [255, 0, 0, 255], - }); - const model = new ReglModel(reGL, { - vs: quad, - fs: globalDefaultprecision + copy, - attributes: { - a_Position: new ReglAttribute(reGL, { - buffer: new ReglBuffer(reGL, { - data: [ - [-4, -4], - [4, -4], - [0, 4], - ], - type: gl.FLOAT, - }), - }), - }, - uniforms: { - // 创建一个红色的纹理 - u_Texture: texture, - }, - depth: { - enable: false, - }, - count: 3, - }); - - reGL.clear({ - color: [0, 0, 0, 0], - }); - - texture.resize({ - width: 1, - height: 1, - }); - - model.draw({}); - - texture.destroy(); - - // 全屏应该都是红色 - expect(checkPixels(reGL, [255])).toBeTruthy(); - }); - - it('should mipmap with default options', () => { - const texture = new ReglTexture2D(reGL, { - width: 1, - height: 1, - data: [255, 0, 0, 255], - mipmap: true, - }); - const model = new ReglModel(reGL, { - vs: quad, - fs: globalDefaultprecision + copy, - attributes: { - a_Position: new ReglAttribute(reGL, { - buffer: new ReglBuffer(reGL, { - data: [ - [-4, -4], - [4, -4], - [0, 4], - ], - type: gl.FLOAT, - }), - }), - }, - uniforms: { - // 创建一个红色的纹理 - u_Texture: texture, - }, - depth: { - enable: false, - }, - count: 3, - }); - - reGL.clear({ - color: [0, 0, 0, 0], - }); - - texture.resize({ - width: 1, - height: 1, - }); - - model.draw({}); - - texture.destroy(); - - // 全屏应该都是红色 - expect(checkPixels(reGL, [255])).toBeTruthy(); - }); - - it('should mipmap with hints', () => { - const texture = new ReglTexture2D(reGL, { - width: 1, - height: 1, - data: [255, 0, 0, 255], - mipmap: gl.DONT_CARE, - }); - const model = new ReglModel(reGL, { - vs: quad, - fs: globalDefaultprecision + copy, - attributes: { - a_Position: new ReglAttribute(reGL, { - buffer: new ReglBuffer(reGL, { - data: [ - [-4, -4], - [4, -4], - [0, 4], - ], - type: gl.FLOAT, - }), - }), - }, - uniforms: { - // 创建一个红色的纹理 - u_Texture: texture, - }, - depth: { - enable: false, - }, - count: 3, - }); - - reGL.clear({ - color: [0, 0, 0, 0], - }); - - texture.resize({ - width: 1, - height: 1, - }); - - model.draw({}); - - texture.destroy(); - - // 全屏应该都是红色 - expect(checkPixels(reGL, [255])).toBeTruthy(); - }); -}); diff --git a/packages/renderer/__tests__/regl/utils/check-pixels.ts b/packages/renderer/__tests__/regl/utils/check-pixels.ts deleted file mode 100644 index fa13d2e428b..00000000000 --- a/packages/renderer/__tests__/regl/utils/check-pixels.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type regl from 'regl'; - -// borrow from https://github.com/regl-project/regl/blob/gh-pages/test/attributes.js#L303-L311 -export default function checkPixels(reGL: regl.Regl, expected: number[]): boolean { - const actual = reGL.read(); - for (let i = 0; i < 1 * 1; ++i) { - if (actual[4 * i] !== expected[i]) { - return false; - } - } - return true; -} diff --git a/packages/renderer/__tests__/regl/utils/default-precision.ts b/packages/renderer/__tests__/regl/utils/default-precision.ts deleted file mode 100644 index 34b008a81ea..00000000000 --- a/packages/renderer/__tests__/regl/utils/default-precision.ts +++ /dev/null @@ -1,3 +0,0 @@ -const globalDefaultprecision = - '#ifdef GL_FRAGMENT_PRECISION_HIGH\n precision highp float;\n #else\n precision mediump float;\n#endif\n'; -export default globalDefaultprecision; diff --git a/packages/renderer/package.json b/packages/renderer/package.json index 2bbaf788b8c..05168e491ae 100644 --- a/packages/renderer/package.json +++ b/packages/renderer/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7-renderer", - "version": "2.21.10", + "version": "2.21.11-beta.7", "description": "", "license": "MIT", "author": "https://github.com/orgs/antvis/people", diff --git a/packages/renderer/src/device/DeviceModel.ts b/packages/renderer/src/device/DeviceModel.ts index 37751e3e4fa..b826d243dd5 100644 --- a/packages/renderer/src/device/DeviceModel.ts +++ b/packages/renderer/src/device/DeviceModel.ts @@ -132,7 +132,7 @@ export default class DeviceModel implements IModel { this.indexBuffer = (elements as DeviceElements).get(); } - const inputLayout = device.createInputLayout({ + const inputLayout = service.renderCache.createInputLayout({ vertexBufferDescriptors, indexBufferFormat: elements ? Format.U32_R : null, program: this.program, @@ -157,7 +157,6 @@ export default class DeviceModel implements IModel { const stencilEnabled = !!(stencilParams && stencilParams.enable); const pipeline = this.device.createRenderPipeline({ - // return this.service.renderCache.createRenderPipeline({ inputLayout: this.inputLayout, program: this.program, topology: primitiveMap[primitive], @@ -270,7 +269,7 @@ export default class DeviceModel implements IModel { ...this.extractUniforms(uniforms), }; - const { renderPass, currentFramebuffer, width, height, renderCache } = this.service; + const { renderPass, currentFramebuffer, width, height } = this.service; // TODO: Recreate pipeline only when blend / cull changed. this.pipeline = this.createPipeline(mergedOptions, pick); @@ -311,8 +310,7 @@ export default class DeviceModel implements IModel { : null, ); if (uniformBuffers) { - // this.bindings = device.createBindings({ - this.bindings = renderCache.createBindings({ + this.bindings = device.createBindings({ pipeline: this.pipeline, uniformBufferBindings: uniformBuffers.map((uniformBuffer, i) => { const buffer = uniformBuffer as DeviceBuffer; @@ -363,7 +361,8 @@ export default class DeviceModel implements IModel { this.vertexBuffers?.forEach((buffer) => buffer.destroy()); this.indexBuffer?.destroy(); this.bindings?.destroy(); - this.inputLayout.destroy(); + // 不能进行销毁,删除 deleteVertexArray + // this.inputLayout.destroy(); this.pipeline.destroy(); this.destroyed = true; } diff --git a/packages/renderer/src/device/index.ts b/packages/renderer/src/device/index.ts index 3095bd00608..b0e37912dc4 100644 --- a/packages/renderer/src/device/index.ts +++ b/packages/renderer/src/device/index.ts @@ -302,7 +302,19 @@ export default class DeviceRendererService implements IRendererService { height, new Uint8Array(width * height * 4), ) as Uint8Array; + + // Since we use U8_RGBA_RT format in render target, need to change bgranorm -> rgba here. + if (this.viewportOrigin !== ViewportOrigin.LOWER_LEFT) { + for (let j = 0; j < result.length; j += 4) { + // Switch b and r components. + const t = result[j]; + result[j] = result[j + 2]; + result[j + 2] = t; + } + } + readback.destroy(); + return result; }; diff --git a/packages/renderer/src/index.ts b/packages/renderer/src/index.ts index 66b481d62e8..6c33f312633 100644 --- a/packages/renderer/src/index.ts +++ b/packages/renderer/src/index.ts @@ -1,6 +1,3 @@ -/** - * - */ import DeviceRendererService from './device'; import ReglRendererService from './regl'; diff --git a/packages/scene/CHANGELOG.md b/packages/scene/CHANGELOG.md index c7bd103950f..cca6ef1d703 100644 --- a/packages/scene/CHANGELOG.md +++ b/packages/scene/CHANGELOG.md @@ -1,5 +1,105 @@ # Change Log +## 2.21.11-beta.7 + +### Patch Changes + +- Updated dependencies [[`3aa0f32`](https://github.com/antvis/L7/commit/3aa0f32b41ef10efa2e9bab46d695bc87ab950f6)]: + - @antv/l7-renderer@2.21.11-beta.7 + - @antv/l7-component@2.21.11-beta.7 + - @antv/l7-layers@2.21.11-beta.7 + - @antv/l7-core@2.21.11-beta.7 + - @antv/l7-maps@2.21.11-beta.7 + - @antv/l7-utils@2.21.11-beta.7 + +## 2.21.11-beta.6 + +### Patch Changes + +- Updated dependencies [[`67647e9`](https://github.com/antvis/L7/commit/67647e95c5b06b593604310c78c6a0ec195c3a01)]: + - @antv/l7-layers@2.21.11-beta.6 + - @antv/l7-component@2.21.11-beta.6 + - @antv/l7-maps@2.21.11-beta.6 + - @antv/l7-renderer@2.21.11-beta.6 + - @antv/l7-core@2.21.11-beta.6 + - @antv/l7-utils@2.21.11-beta.6 + +## 2.21.11-beta.5 + +### Patch Changes + +- Updated dependencies [[`8939e9b`](https://github.com/antvis/L7/commit/8939e9bc0e744d75b5b469c221d6695c7a313e83)]: + - @antv/l7-maps@2.21.11-beta.5 + - @antv/l7-layers@2.21.11-beta.5 + - @antv/l7-component@2.21.11-beta.5 + - @antv/l7-renderer@2.21.11-beta.5 + - @antv/l7-core@2.21.11-beta.5 + - @antv/l7-utils@2.21.11-beta.5 + +## 2.21.11-beta.4 + +### Patch Changes + +- Updated dependencies [[`cca16a3`](https://github.com/antvis/L7/commit/cca16a3d72de462afa9d71c386c82f92952d1c47)]: + - @antv/l7-maps@2.21.11-beta.4 + - @antv/l7-layers@2.21.11-beta.4 + - @antv/l7-component@2.21.11-beta.4 + - @antv/l7-renderer@2.21.11-beta.4 + - @antv/l7-core@2.21.11-beta.4 + - @antv/l7-utils@2.21.11-beta.4 + +## 2.21.11-beta.3 + +### Patch Changes + +- Updated dependencies [[`aca779d`](https://github.com/antvis/L7/commit/aca779dac55ebf9ee1116106d69e71bb872b4ccc), [`a5f57ed`](https://github.com/antvis/L7/commit/a5f57eda52dab160fe076f252ad52cd51b8f456a)]: + - @antv/l7-component@2.21.11-beta.3 + - @antv/l7-core@2.21.11-beta.3 + - @antv/l7-layers@2.21.11-beta.3 + - @antv/l7-maps@2.21.11-beta.3 + - @antv/l7-renderer@2.21.11-beta.3 + - @antv/l7-utils@2.21.11-beta.3 + +## 2.21.11-beta.2 + +### Patch Changes + +- Updated dependencies [[`0754eeb`](https://github.com/antvis/L7/commit/0754eebe5c029c808958a5f29492ed2487263c7f)]: + - @antv/l7-layers@2.21.11-beta.2 + - @antv/l7-component@2.21.11-beta.2 + - @antv/l7-renderer@2.21.11-beta.2 + - @antv/l7-core@2.21.11-beta.2 + - @antv/l7-maps@2.21.11-beta.2 + - @antv/l7-utils@2.21.11-beta.2 + +## 2.21.11-beta.1 + +### Patch Changes + +- [#2477](https://github.com/antvis/L7/pull/2477) [`05dd5cc`](https://github.com/antvis/L7/commit/05dd5ccf31e12a9440efbebc9fcb803c594b5a44) Thanks [@lvisei](https://github.com/lvisei)! - feat: 设置默认的渲染引擎为 g-device,优先使用 WebGL2 + +- Updated dependencies []: + - @antv/l7-component@2.21.11-beta.1 + - @antv/l7-layers@2.21.11-beta.1 + - @antv/l7-renderer@2.21.11-beta.1 + - @antv/l7-core@2.21.11-beta.1 + - @antv/l7-maps@2.21.11-beta.1 + - @antv/l7-utils@2.21.11-beta.1 + +## 2.21.11-beta.0 + +### Patch Changes + +- [#2477](https://github.com/antvis/L7/pull/2477) [`05dd5cc`](https://github.com/antvis/L7/commit/05dd5ccf31e12a9440efbebc9fcb803c594b5a44) Thanks [@lvisei](https://github.com/lvisei)! - feat: 设置默认的渲染引擎为 g-device,优先使用 WebGL2 + +- Updated dependencies [[`3e33888`](https://github.com/antvis/L7/commit/3e33888a56c6efa80be60bc79182644eaccaa500), [`8b72df1`](https://github.com/antvis/L7/commit/8b72df14dc18ba85f66f8e4e09ba9d80d0379ed3), [`d408bdb`](https://github.com/antvis/L7/commit/d408bdb4a2a7be57a50f9a88247cf7b690ba4387)]: + - @antv/l7-layers@2.21.11-beta.0 + - @antv/l7-renderer@2.21.11-beta.0 + - @antv/l7-component@2.21.11-beta.0 + - @antv/l7-core@2.21.11-beta.0 + - @antv/l7-maps@2.21.11-beta.0 + - @antv/l7-utils@2.21.11-beta.0 + ## 2.21.10 ### Patch Changes diff --git a/packages/scene/package.json b/packages/scene/package.json index 1f68cb8a218..67f488149ac 100644 --- a/packages/scene/package.json +++ b/packages/scene/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7-scene", - "version": "2.21.10", + "version": "2.21.11-beta.7", "description": "", "license": "MIT", "author": "https://github.com/orgs/antvis/people", diff --git a/packages/scene/src/index.ts b/packages/scene/src/index.ts index 91b6090ff89..39cc35f1f5d 100644 --- a/packages/scene/src/index.ts +++ b/packages/scene/src/index.ts @@ -64,12 +64,12 @@ class Scene implements IPostProcessingPassPluggable, IMapController, ILayerManag private container: L7Container; public constructor(config: ISceneConfig) { - const { id, map, canvas, renderer = 'regl' } = config; + const { id, map, renderer = 'device' } = config; // 创建场景容器 const sceneContainer = createSceneContainer(); this.container = sceneContainer; // 绑定地图服务 - map.setContainer(sceneContainer, id, canvas); + map.setContainer(sceneContainer, id); if (renderer === 'regl') { sceneContainer.rendererService = new ReglRendererService(); } else { diff --git a/packages/source/CHANGELOG.md b/packages/source/CHANGELOG.md index f574e90981d..e91e8bc30d7 100644 --- a/packages/source/CHANGELOG.md +++ b/packages/source/CHANGELOG.md @@ -1,5 +1,69 @@ # Change Log +## 2.21.11-beta.7 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.7 + - @antv/l7-utils@2.21.11-beta.7 + +## 2.21.11-beta.6 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.6 + - @antv/l7-utils@2.21.11-beta.6 + +## 2.21.11-beta.5 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.5 + - @antv/l7-utils@2.21.11-beta.5 + +## 2.21.11-beta.4 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.4 + - @antv/l7-utils@2.21.11-beta.4 + +## 2.21.11-beta.3 + +### Patch Changes + +- Updated dependencies [[`a5f57ed`](https://github.com/antvis/L7/commit/a5f57eda52dab160fe076f252ad52cd51b8f456a)]: + - @antv/l7-core@2.21.11-beta.3 + - @antv/l7-utils@2.21.11-beta.3 + +## 2.21.11-beta.2 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.2 + - @antv/l7-utils@2.21.11-beta.2 + +## 2.21.11-beta.1 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.1 + - @antv/l7-utils@2.21.11-beta.1 + +## 2.21.11-beta.0 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-core@2.21.11-beta.0 + - @antv/l7-utils@2.21.11-beta.0 + ## 2.21.10 ### Patch Changes diff --git a/packages/source/package.json b/packages/source/package.json index 300ce188102..bcd68d470a2 100644 --- a/packages/source/package.json +++ b/packages/source/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7-source", - "version": "2.21.10", + "version": "2.21.11-beta.7", "description": "", "license": "MIT", "author": "https://github.com/orgs/antvis/people", diff --git a/packages/test-utils/CHANGELOG.md b/packages/test-utils/CHANGELOG.md index 30fc294558e..1722da36257 100644 --- a/packages/test-utils/CHANGELOG.md +++ b/packages/test-utils/CHANGELOG.md @@ -1,5 +1,77 @@ # @antv/l7-test-utils +## 2.21.11-beta.7 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-scene@2.21.11-beta.7 + - @antv/l7-map@2.21.11-beta.7 + - @antv/l7-maps@2.21.11-beta.7 + +## 2.21.11-beta.6 + +### Patch Changes + +- Updated dependencies [[`7e38a83`](https://github.com/antvis/L7/commit/7e38a83d9324fb9443f5a04e6d2fc9a1fef9c17c)]: + - @antv/l7-map@2.21.11-beta.6 + - @antv/l7-scene@2.21.11-beta.6 + - @antv/l7-maps@2.21.11-beta.6 + +## 2.21.11-beta.5 + +### Patch Changes + +- Updated dependencies [[`8939e9b`](https://github.com/antvis/L7/commit/8939e9bc0e744d75b5b469c221d6695c7a313e83)]: + - @antv/l7-maps@2.21.11-beta.5 + - @antv/l7-scene@2.21.11-beta.5 + - @antv/l7-map@2.21.11-beta.5 + +## 2.21.11-beta.4 + +### Patch Changes + +- Updated dependencies [[`cca16a3`](https://github.com/antvis/L7/commit/cca16a3d72de462afa9d71c386c82f92952d1c47)]: + - @antv/l7-maps@2.21.11-beta.4 + - @antv/l7-scene@2.21.11-beta.4 + - @antv/l7-map@2.21.11-beta.4 + +## 2.21.11-beta.3 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-scene@2.21.11-beta.3 + - @antv/l7-maps@2.21.11-beta.3 + - @antv/l7-map@2.21.11-beta.3 + +## 2.21.11-beta.2 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7-scene@2.21.11-beta.2 + - @antv/l7-map@2.21.11-beta.2 + - @antv/l7-maps@2.21.11-beta.2 + +## 2.21.11-beta.1 + +### Patch Changes + +- Updated dependencies [[`05dd5cc`](https://github.com/antvis/L7/commit/05dd5ccf31e12a9440efbebc9fcb803c594b5a44)]: + - @antv/l7-scene@2.21.11-beta.1 + - @antv/l7-map@2.21.11-beta.1 + - @antv/l7-maps@2.21.11-beta.1 + +## 2.21.11-beta.0 + +### Patch Changes + +- Updated dependencies [[`05dd5cc`](https://github.com/antvis/L7/commit/05dd5ccf31e12a9440efbebc9fcb803c594b5a44)]: + - @antv/l7-scene@2.21.11-beta.0 + - @antv/l7-map@2.21.11-beta.0 + - @antv/l7-maps@2.21.11-beta.0 + ## 2.21.10 ### Patch Changes diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index a4e5cfc8021..cbc2c11ddcf 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7-test-utils", - "version": "2.21.10", + "version": "2.21.11-beta.7", "private": true, "description": "Test utils for L7", "keywords": [], diff --git a/packages/test-utils/src/gl-context.ts b/packages/test-utils/src/gl-context.ts index 7334a2eb1b4..abe0b80a1e6 100644 --- a/packages/test-utils/src/gl-context.ts +++ b/packages/test-utils/src/gl-context.ts @@ -1,4 +1,8 @@ import gl from 'gl'; /** Test context */ -export const glContext = gl(1, 1, { preserveDrawingBuffer: true }); +export const glContext = gl(1, 1, { + preserveDrawingBuffer: true, + antialias: false, + stencil: true, +}); diff --git a/packages/test-utils/src/test-scene.ts b/packages/test-utils/src/test-scene.ts index 4324aa167de..106b7b0ce55 100644 --- a/packages/test-utils/src/test-scene.ts +++ b/packages/test-utils/src/test-scene.ts @@ -1,15 +1,24 @@ -import type { IMapOptions } from '@antv/l7-map'; +import type { IMapConfig } from '@antv/l7-core'; import { Map } from '@antv/l7-maps'; import { Scene } from '@antv/l7-scene'; -import regl from 'regl'; import { glContext } from './gl-context'; -export function TestScene(options?: Partial) { +export function TestScene(options?: Partial) { const el = document.createElement('div'); el.id = 'test-div-id'; const width = 400; const height = 300; + const mockCanvas = document.createElement('canvas'); + // @ts-ignore + mockCanvas.getContext = () => { + // @ts-ignore + glContext.canvas = mockCanvas; + // 模拟 DOM API,返回小程序 context,它应当和 CanvasRenderingContext2D 一致 + // @see https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCanvasElement/getContext + return glContext; + }; + const body = document.querySelector('body') as HTMLBodyElement; body.appendChild(el); // @ts-ignore @@ -24,37 +33,9 @@ export function TestScene(options?: Partial) { left: 0, })); - const reGL = regl({ - gl: glContext, - attributes: { - alpha: true, - // use TAA instead of MSAA - // @see https://www.khronos.org/registry/webgl/specs/1.0/#5.2.1 - antialias: true, - premultipliedAlpha: true, - preserveDrawingBuffer: false, - - stencil: true, - }, - extensions: [ - 'ANGLE_instanced_arrays', - 'STACKGL_resize_drawingbuffer', - 'STACKGL_destroy_context', - 'OES_element_index_uint', - 'OES_standard_derivatives', - 'OES_texture_float', - 'OES_texture_float_linear', - 'WEBGL_draw_buffers', - 'EXT_blend_minmax', - 'EXT_texture_filter_anisotropic', - 'OES_vertex_array_object', - ], - }); const scene = new Scene({ id: el, - // TODO: switch to device support mock canvas - // see https://github.com/antvis/g-device-api/blob/master/__tests__/utils.ts#L43C3-L47C6 - gl: reGL, + canvas: mockCanvas, map: new Map({ style: 'dark', center: [110.19382669582967, 30.258134], diff --git a/packages/three/CHANGELOG.md b/packages/three/CHANGELOG.md index 1c886a0da34..3e1aa9f6f4c 100644 --- a/packages/three/CHANGELOG.md +++ b/packages/three/CHANGELOG.md @@ -1,5 +1,61 @@ # @antv/l7-three +## 2.21.11-beta.7 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7@2.21.11-beta.7 + +## 2.21.11-beta.6 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7@2.21.11-beta.6 + +## 2.21.11-beta.5 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7@2.21.11-beta.5 + +## 2.21.11-beta.4 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7@2.21.11-beta.4 + +## 2.21.11-beta.3 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7@2.21.11-beta.3 + +## 2.21.11-beta.2 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7@2.21.11-beta.2 + +## 2.21.11-beta.1 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7@2.21.11-beta.1 + +## 2.21.11-beta.0 + +### Patch Changes + +- Updated dependencies []: + - @antv/l7@2.21.11-beta.0 + ## 2.21.10 ### Patch Changes diff --git a/packages/three/package.json b/packages/three/package.json index c69e6040a44..5bdb83fb847 100644 --- a/packages/three/package.json +++ b/packages/three/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7-three", - "version": "2.21.10", + "version": "2.21.11-beta.7", "description": "Three for L7 ", "keywords": [ "3D", diff --git a/packages/three/src/core/baseLayer.ts b/packages/three/src/core/baseLayer.ts index 05742a2a092..1d28094bcfd 100644 --- a/packages/three/src/core/baseLayer.ts +++ b/packages/three/src/core/baseLayer.ts @@ -110,12 +110,8 @@ export default class ThreeJSLayer * @returns */ public lnglatToCoord(lnglat: ILngLat) { - // @ts-ignore - const [x, y] = this.mapService?.lngLatToCoord( - lnglat, - // @ts-ignore - this.threeRenderService.center, - ) || [0, 0]; + const { x, y } = this.mapService.lngLatToMercator(lnglat, 0); + // const origin = this.threeRenderService.center || [0, 0] return [x, y] as ILngLat; } @@ -159,7 +155,6 @@ export default class ThreeJSLayer } public async buildModels() { - console.log(this.container); // @ts-ignore this.threeRenderService = this.container.customRenderService['three']; const config = this.getLayerConfig(); diff --git a/packages/three/src/core/threeRenderService.ts b/packages/three/src/core/threeRenderService.ts index 405ff40f521..168c50455ae 100644 --- a/packages/three/src/core/threeRenderService.ts +++ b/packages/three/src/core/threeRenderService.ts @@ -1,7 +1,7 @@ import type { IMapService, IMercator, IRendererService } from '@antv/l7'; import type { Camera } from 'three'; import { Matrix4, PerspectiveCamera, Scene as ThreeScene, WebGLRenderer } from 'three'; -const DEG2RAD = Math.PI / 180; + export interface IThreeRenderService { renderer: WebGLRenderer; camera: Camera; @@ -58,28 +58,18 @@ export class ThreeRenderService implements IThreeRenderService { this.aspect = gl.drawingBufferWidth / gl.drawingBufferHeight; this.camera = new PerspectiveCamera(45, this.aspect, 1, 20000000); } + public getRenderCamera(): Camera { - /** - * map version - * GAODE1.x - * GAODE2.x - * MAPBOX - */ - switch (this.mapService.version) { - case 'GAODE1.x': + switch (this.mapService.getType()) { + case 'amap': return this.AMapCamera(); - case 'GAODE2.x': - return this.AMap2Camera(); - case 'MAPBOX': + case 'mapbox': return this.mapboxCamera(); - case 'DEFAULTMAP': + case 'default': return this.mapboxCamera(); default: - return this.AMapCamera(); + throw new Error('不支持其它地图'); } - // return this.mapService.constructor.name === 'AMapService' - // ? this.AMapCamera() - // : this.mapboxCamera(); } private mapboxCamera(): Camera { @@ -92,39 +82,9 @@ export class ThreeRenderService implements IThreeRenderService { } private AMapCamera(): Camera { - // @ts-ignore - const mapCamera = this.mapService.map.getCameraState(); - const camera = this.camera; - let { pitch, rotation } = mapCamera; - const { fov, near, far, height, aspect } = mapCamera; - pitch *= DEG2RAD; - rotation *= DEG2RAD; - // @ts-ignore - camera.fov = (180 * fov) / Math.PI; - // @ts-ignore - camera.aspect = aspect; - // @ts-ignore - camera.near = near; - // @ts-ignore - camera.far = far; - // @ts-ignore - camera.updateProjectionMatrix(); - camera.position.z = height * Math.cos(pitch); - camera.position.x = height * Math.sin(pitch) * Math.sin(rotation); - camera.position.y = -height * Math.sin(pitch) * Math.cos(rotation); - camera.up.x = -Math.cos(pitch) * Math.sin(rotation); - camera.up.y = Math.cos(pitch) * Math.cos(rotation); - camera.up.z = Math.sin(pitch); - camera.lookAt(0, 0, 0); - camera.position.x += mapCamera.position.x; - camera.position.y += -mapCamera.position.y; - return camera; - } - - private AMap2Camera(): Camera { - // @ts-ignore + // @ts-expect-error const customCoords = this.mapService.map.customCoords; - customCoords.getCenter(); + customCoords.setCenter([0, 0]); const camera = this.camera; const { near, far, fov, up, lookAt, position } = customCoords.getCameraParams(); diff --git a/packages/utils/CHANGELOG.md b/packages/utils/CHANGELOG.md index 5a94f8f84a5..4038c846f56 100644 --- a/packages/utils/CHANGELOG.md +++ b/packages/utils/CHANGELOG.md @@ -1,5 +1,21 @@ # Change Log +## 2.21.11-beta.7 + +## 2.21.11-beta.6 + +## 2.21.11-beta.5 + +## 2.21.11-beta.4 + +## 2.21.11-beta.3 + +## 2.21.11-beta.2 + +## 2.21.11-beta.1 + +## 2.21.11-beta.0 + ## 2.21.10 ## 2.21.9 diff --git a/packages/utils/__tests__/lineAtOffset.spec.ts b/packages/utils/__tests__/lineAtOffset.spec.ts index 08ecfdfb353..583f9b20224 100644 --- a/packages/utils/__tests__/lineAtOffset.spec.ts +++ b/packages/utils/__tests__/lineAtOffset.spec.ts @@ -1,5 +1,5 @@ -import { MapType } from '../src/interface/map'; import { lineAtOffset } from '../src/lineAtOffset/index'; + const arcSource = { inited: true, data: { @@ -17,68 +17,12 @@ const arcSource = { }; describe('lineAtOffset', () => { - // (async () => { - // const asyncOffsetPoint = await lineAtOffsetAsyc(arcSource, { - // shape: 'arc', - // offset: 0.1, - // mapVersion: Version['GAODE1.x'], - // }); - // it('asyncOffsetPoint', async () => { - // expect(asyncOffsetPoint).toEqual([ - // { - // coordinates: [ - // [99.228515625, 37.43997405227057], - // [100.72265625, 27.994401411046148], - // ], - // offset: 0.3, - // id: 0, - // lng: 99.66757224332352, - // lat: 36.507847734146466, - // height: 0, - // }, - // ]); - // }); - // })(); - const arcOffsetPoint = lineAtOffset(arcSource, { - shape: 'arc', - offset: 0.1, - mapVersion: MapType['GAODE1.x'], - }); - - const arcOffsetPoint2 = lineAtOffset(arcSource, { - shape: 'arc', - offset: 0.1, - mapVersion: MapType['GAODE2.x'], - thetaOffset: 0.314, - }); - - const arcOffsetPoint3 = lineAtOffset(arcSource, { - shape: 'arc', - offset: 0.1, - mapVersion: MapType['GAODE2.x'], - thetaOffset: 0.314, - featureId: 0, - }); - - const greatCircleOffsetPoint = lineAtOffset(arcSource, { - shape: 'greatcircle', - offset: 0.1, - mapVersion: MapType['GAODE1.x'], - }); - - const greatCircleOffsetPoint2 = lineAtOffset(arcSource, { - shape: 'greatcircle', - offset: 0.1, - mapVersion: MapType['GAODE2.x'], - }); - - const lineOffsetPoint = lineAtOffset(arcSource, { - shape: 'line', - offset: 0.1, - mapVersion: MapType['GAODE1.x'], - }); - it('arcOffsetPoint', () => { + const arcOffsetPoint = lineAtOffset(arcSource, { + shape: 'arc', + offset: 0.1, + }); + expect(arcOffsetPoint).toEqual([ { coordinates: [ @@ -94,7 +38,13 @@ describe('lineAtOffset', () => { ]); }); - it('arcOffsetPoint2', () => { + it('arcOffsetPoint thetaOffset', () => { + const arcOffsetPoint2 = lineAtOffset(arcSource, { + shape: 'arc', + offset: 0.1, + thetaOffset: 0.314, + }); + expect(arcOffsetPoint2).toEqual([ { coordinates: [ @@ -103,14 +53,21 @@ describe('lineAtOffset', () => { ], offset: 0.3, id: 0, - lng: 99.72191962749187, - lat: 36.54640697914567, + lat: 36.507847734146466, + lng: 99.66757224332352, height: 0, }, ]); }); - it('arcOffsetPoint3', () => { + it('arcOffsetPoint featureId', () => { + const arcOffsetPoint3 = lineAtOffset(arcSource, { + shape: 'arc', + offset: 0.1, + thetaOffset: 0.314, + featureId: 0, + }); + expect(arcOffsetPoint3).toEqual([ { coordinates: [ @@ -119,14 +76,19 @@ describe('lineAtOffset', () => { ], height: 0, id: 0, - lat: 36.54640697914567, - lng: 99.72191962749187, + lat: 36.507847734146466, + lng: 99.66757224332352, offset: 0.3, }, ]); }); it('greatCircleOffsetPoint', () => { + const greatCircleOffsetPoint = lineAtOffset(arcSource, { + shape: 'greatcircle', + offset: 0.1, + }); + expect(greatCircleOffsetPoint).toEqual([ { coordinates: [ @@ -142,23 +104,12 @@ describe('lineAtOffset', () => { ]); }); - it('greatCircleOffsetPoint2', () => { - expect(greatCircleOffsetPoint2).toEqual([ - { - coordinates: [ - [99.228515625, 37.43997405227057], - [100.72265625, 27.994401411046148], - ], - offset: 0.3, - id: 0, - lng: 1.7395272931153063, - lat: 0.6371821457776072, - height: 0, - }, - ]); - }); - it('lineOffsetPoint', () => { + const lineOffsetPoint = lineAtOffset(arcSource, { + shape: 'line', + offset: 0.1, + }); + expect(lineOffsetPoint).toEqual([ { coordinates: [ diff --git a/packages/utils/package.json b/packages/utils/package.json index 6d74e2db49e..3f6fede6158 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@antv/l7-utils", - "version": "2.21.10", + "version": "2.21.11-beta.7", "description": "Utils for L7", "license": "MIT", "author": "https://github.com/orgs/antvis/people", diff --git a/packages/utils/src/cull.ts b/packages/utils/src/cull.ts deleted file mode 100644 index a4a6cb40641..00000000000 --- a/packages/utils/src/cull.ts +++ /dev/null @@ -1,34 +0,0 @@ -const gl = { - BACK: 1029, - FRONT: 1028, -}; -export function getCullFace(mapVersion: string | undefined): number { - // 'GAODE1.x' = 'GAODE1.x', - // 'GAODE2.x' = 'GAODE2.x', - // 'MAPBOX' = 'MAPBOX', - // 'DEFAULT' = 'DEFAULTMAP', - // 'SIMPLE' = 'SIMPLE', - // 'GLOBEL' = 'GLOBEL', - switch (mapVersion) { - case 'GAODE1.x': - return gl.BACK; - break; - case 'GAODE2.x': - return gl.BACK; - break; - case 'MAPBOX': - return gl.FRONT; - break; - case 'SIMPLE': - return gl.FRONT; - break; - case 'GLOBEL': - return gl.BACK; - break; - case 'DEBAULT': - return gl.FRONT; - break; - default: - return gl.FRONT; - } -} diff --git a/packages/utils/src/geo.ts b/packages/utils/src/geo.ts index eac2b8ec575..50d8d000108 100644 --- a/packages/utils/src/geo.ts +++ b/packages/utils/src/geo.ts @@ -65,6 +65,11 @@ function transform(item: any[], cb: (item: any[]) => any): any { return cb(item); } export function lngLatToMeters(lnglat: Point): Point; +export function lngLatToMeters( + lnglat: Point, + validate?: boolean, + accuracy?: { enable: boolean; decimal: number }, +): Point; export function lngLatToMeters( lnglat: Point, validate: boolean = true, diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index ecdab195e96..1f27c3870bf 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -1,9 +1,7 @@ -// @ts-ignore export * from './ajax'; export * from './anchor'; export * from './color'; export * from './config'; -export * from './cull'; export * as DOM from './dom'; export * from './env'; export * from './event'; @@ -12,10 +10,10 @@ export { BKDRHash, djb2hash, guid } from './hash'; export * from './lineAtOffset'; export * from './lodash-adapter'; export * from './lru_cache'; -// export * from './mini-adapter/index'; -export * from './interface/map'; +export * from './math'; export * as Satistics from './statistics'; export * from './tileset-manager'; + export function defaultValue(v1: any, v2: any) { if (v1 === undefined || v1 === null) { return v2; diff --git a/packages/utils/src/interface/map.ts b/packages/utils/src/interface/map.ts deleted file mode 100644 index f0fffec64f1..00000000000 --- a/packages/utils/src/interface/map.ts +++ /dev/null @@ -1,8 +0,0 @@ -export enum MapType { - 'GAODE1.x' = 'GAODE1.x', - 'GAODE2.x' = 'GAODE2.x', - 'MAPBOX' = 'MAPBOX', - 'DEFAULT' = 'DEFAUlTMAP', - 'SIMPLE' = 'SIMPLE', - 'GLOBEL' = 'GLOBEL', -} diff --git a/packages/utils/src/lineAtOffset/arc.ts b/packages/utils/src/lineAtOffset/arc.ts index a9009221749..ca7ac0cbd74 100644 --- a/packages/utils/src/lineAtOffset/arc.ts +++ b/packages/utils/src/lineAtOffset/arc.ts @@ -1,5 +1,3 @@ -import { amap2Project, amap2UnProject } from '../geo'; -import { MapType } from '../interface/map'; import type { Point } from './interface'; // arc export function arcLineAtOffset( @@ -7,7 +5,6 @@ export function arcLineAtOffset( target: Point, offset: number, thetaOffset: number | undefined, - mapVersion: MapType | undefined, segmentNumber: number = 30, autoFit: boolean, ) { @@ -19,9 +16,9 @@ export function arcLineAtOffset( } if (!thetaOffset) { - return interpolate(source, target, pointOffset, 0.314, mapVersion); + return interpolate(source, target, pointOffset, 0.314); } else { - return interpolate(source, target, pointOffset, thetaOffset, mapVersion); + return interpolate(source, target, pointOffset, thetaOffset); } } @@ -44,29 +41,10 @@ function midPoint(source: Point, target: Point, thetaOffset: number) { return mid; } -function interpolate( - source: Point, - target: Point, - offset: number, - thetaOffset: number, - mapVersion?: MapType, -) { - if (mapVersion === MapType['GAODE2.x']) { - // amap2 - const sourceFlat = amap2Project(source[0], source[1]); - const targetFlat = amap2Project(target[0], target[1]); - - const mid = midPoint(sourceFlat, targetFlat, thetaOffset); - - const x = [sourceFlat[0], mid[0], targetFlat[0]]; - const y = [sourceFlat[1], mid[1], targetFlat[1]]; - - return [...amap2UnProject(bezier3(x, offset), bezier3(y, offset)), 0]; - } else { - // amap - const mid = midPoint(source, target, thetaOffset); - const x = [source[0], mid[0], target[0]]; - const y = [source[1], mid[1], target[1]]; - return [bezier3(x, offset), bezier3(y, offset), 0]; - } +function interpolate(source: Point, target: Point, offset: number, thetaOffset: number) { + // amap + const mid = midPoint(source, target, thetaOffset); + const x = [source[0], mid[0], target[0]]; + const y = [source[1], mid[1], target[1]]; + return [bezier3(x, offset), bezier3(y, offset), 0]; } diff --git a/packages/utils/src/lineAtOffset/greatCircle.ts b/packages/utils/src/lineAtOffset/greatCircle.ts index 9618d723fc4..ef5f466efe8 100644 --- a/packages/utils/src/lineAtOffset/greatCircle.ts +++ b/packages/utils/src/lineAtOffset/greatCircle.ts @@ -1,6 +1,4 @@ import { degreesToRadians, radiansToDegrees } from '@turf/helpers'; -import { calDistance } from '../geo'; -import type { MapType } from '../interface/map'; import type { Point } from './interface'; // arc export function greatCircleLineAtOffset( @@ -8,7 +6,6 @@ export function greatCircleLineAtOffset( target: Point, offset: number, thetaOffset: number | undefined, - mapVersion: MapType | undefined, // eslint-disable-next-line @typescript-eslint/no-unused-vars segmentNumber: number = 30, autoFit: boolean, @@ -19,23 +16,7 @@ export function greatCircleLineAtOffset( // greatcircle 暂时不支持配置 segmentNumber 和 thetaOffset pointOffset = Math.round(offset * 29) / 29; } - return interpolate(source, target, pointOffset, mapVersion); -} - -function midPoint(source: Point, target: Point) { - const center = [target[0] - source[0], target[1] - source[1]]; // target - source; - const r = calDistance(center, [0, 0]); - const theta = Math.atan2(center[1], center[0]); - const thetaOffset = 0.314; - const r2 = r / 2.0 / Math.cos(thetaOffset); - const theta2 = theta + thetaOffset; - const mid = [r2 * Math.cos(theta2) + source[0], r2 * Math.sin(theta2) + source[1]]; - return mid; -} - -function bezier3(arr: Point, t: number) { - const ut = 1 - t; - return (arr[0] * ut + arr[1] * t) * ut + (arr[1] * ut + arr[2] * t) * t; + return interpolate(source, target, pointOffset); } function getAngularDist(source: Point, target: Point) { @@ -47,35 +28,28 @@ function getAngularDist(source: Point, target: Point) { return 2.0 * Math.atan2(Math.sqrt(a), Math.sqrt(1.0 - a)); } -export function interpolate(s: Point, t: Point, offset: number, mapVersion: string | undefined) { +export function interpolate(s: Point, t: Point, offset: number) { const source = [degreesToRadians(s[0]), degreesToRadians(s[1])]; const target = [degreesToRadians(t[0]), degreesToRadians(t[1])]; - if (mapVersion === 'GAODE2.x') { - // gaode2.x - const mid = midPoint(source, target); - const x = [source[0], mid[0], target[0]]; - const y = [source[1], mid[1], target[1]]; - return [bezier3(x, offset), bezier3(y, offset), 0]; - } else { - const angularDist = getAngularDist(source, target); - if (Math.abs(angularDist - Math.PI) < 0.001) { - return [ - (1.0 - offset) * source[0] + offset * target[0], - (1.0 - offset) * source[1] + offset * target[1], - ]; - } - const a = Math.sin((1.0 - offset) * angularDist) / Math.sin(angularDist); - const b = Math.sin(offset * angularDist) / Math.sin(angularDist); - const sinSource = [Math.sin(source[0]), Math.sin(source[1])]; - const cosSource = [Math.cos(source[0]), Math.cos(source[1])]; - const sinTarget = [Math.sin(target[0]), Math.sin(target[1])]; - const cosTarget = [Math.cos(target[0]), Math.cos(target[1])]; - const x = a * cosSource[1] * cosSource[0] + b * cosTarget[1] * cosTarget[0]; - const y = a * cosSource[1] * sinSource[0] + b * cosTarget[1] * sinTarget[0]; - const z = a * sinSource[1] + b * sinTarget[1]; + + const angularDist = getAngularDist(source, target); + if (Math.abs(angularDist - Math.PI) < 0.001) { return [ - radiansToDegrees(Math.atan2(y, x)), - radiansToDegrees(Math.atan2(z, Math.sqrt(x * x + y * y))), + (1.0 - offset) * source[0] + offset * target[0], + (1.0 - offset) * source[1] + offset * target[1], ]; } + const a = Math.sin((1.0 - offset) * angularDist) / Math.sin(angularDist); + const b = Math.sin(offset * angularDist) / Math.sin(angularDist); + const sinSource = [Math.sin(source[0]), Math.sin(source[1])]; + const cosSource = [Math.cos(source[0]), Math.cos(source[1])]; + const sinTarget = [Math.sin(target[0]), Math.sin(target[1])]; + const cosTarget = [Math.cos(target[0]), Math.cos(target[1])]; + const x = a * cosSource[1] * cosSource[0] + b * cosTarget[1] * cosTarget[0]; + const y = a * cosSource[1] * sinSource[0] + b * cosTarget[1] * sinTarget[0]; + const z = a * sinSource[1] + b * sinTarget[1]; + return [ + radiansToDegrees(Math.atan2(y, x)), + radiansToDegrees(Math.atan2(z, Math.sqrt(x * x + y * y))), + ]; } diff --git a/packages/utils/src/lineAtOffset/index.ts b/packages/utils/src/lineAtOffset/index.ts index 0c554e2ea63..b54510e29a2 100644 --- a/packages/utils/src/lineAtOffset/index.ts +++ b/packages/utils/src/lineAtOffset/index.ts @@ -31,7 +31,7 @@ export function lineAtOffsetAsyc(source: Source, option: ILineAtOffset) { } function getLineOffsetPosition(feature: any, option: ILineAtOffset) { - const { offset, shape, thetaOffset, mapVersion, segmentNumber = 30, autoFit = true } = option; + const { offset, shape, thetaOffset, segmentNumber = 30, autoFit = true } = option; const { coordinates } = feature; if (shape === 'line') { return pathLineAtOffset(coordinates, offset); @@ -57,7 +57,6 @@ function getLineOffsetPosition(feature: any, option: ILineAtOffset) { target, offset, linetheatOffset, - mapVersion, segmentNumber, autoFit, ); diff --git a/packages/utils/src/lineAtOffset/interface.ts b/packages/utils/src/lineAtOffset/interface.ts index 78d4def4d79..bf3927f9519 100644 --- a/packages/utils/src/lineAtOffset/interface.ts +++ b/packages/utils/src/lineAtOffset/interface.ts @@ -1,4 +1,3 @@ -import type { MapType } from '../interface/map'; export type Source = any; export type ILineShape = 'line' | 'arc' | 'arc3d' | 'greatcircle'; export type IThetaOffset = string | number | undefined; @@ -7,7 +6,6 @@ export type Point = number[]; export interface ILineAtOffset { offset: number; shape: ILineShape; - mapVersion: MapType; thetaOffset?: IThetaOffset; featureId?: number | undefined; segmentNumber?: number; diff --git a/packages/utils/src/lodash-adapter.ts b/packages/utils/src/lodash-adapter.ts index 6444b8bd7b2..75734bb2a0f 100644 --- a/packages/utils/src/lodash-adapter.ts +++ b/packages/utils/src/lodash-adapter.ts @@ -32,6 +32,8 @@ import isUndefined from 'lodash/isUndefined'; // camelCase import camelCase from 'lodash/camelCase'; +import uniqueId from 'lodash/uniqueId'; + export type { DebouncedFunc } from 'lodash'; export const lodashUtil = { @@ -56,4 +58,5 @@ export const lodashUtil = { isObject, isUndefined, camelCase, + uniqueId, }; diff --git a/packages/utils/src/math.ts b/packages/utils/src/math.ts index f98e5617c8c..fc573a90016 100644 --- a/packages/utils/src/math.ts +++ b/packages/utils/src/math.ts @@ -1,3 +1,12 @@ export function isNumber(n: any) { return typeof n === 'number'; } + +/** + * Calculate the low part of a WebGL 64 bit float + * @param x {number} - the input float number + * @returns {number} - the lower 32 bit of the number + */ +export function fp64LowPart(x: number): number { + return x - Math.fround(x); +} diff --git a/scripts/cloc-code.sh b/scripts/cloc-code.sh new file mode 100755 index 00000000000..9ed9e026ce5 --- /dev/null +++ b/scripts/cloc-code.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# cloc from https://github.com/AlDanial/cloc + +cloc packages/*/src --exclude-dir=test-utils --exclude-lang=SVG,LESS + +# output like: +# ------------------------------------------------------------------------------- +# Language files blank comment code +# ------------------------------------------------------------------------------- +# TypeScript 434 5726 5798 44103 +# GLSL 112 946 322 4234 +# CSS 9 16 2 826 +# JavaScript 1 0 1 68 +# ------------------------------------------------------------------------------- +# SUM: 556 6688 6123 49231 +# ------------------------------------------------------------------------------- diff --git a/site/docs/api/other/plane.en.md b/site/docs/api/other/plane.en.md index eb5fb5dafc2..1ddb637cf6d 100644 --- a/site/docs/api/other/plane.en.md +++ b/site/docs/api/other/plane.en.md @@ -50,8 +50,8 @@ const layer = new GeometryLayer().shape('plane').style({ terrainTexture: 'https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*eYFaRYlnnOUAAAAAAAAAAAAAARQnAQ', rgb2height: (r, g, b) => { - let h = -10000.0 + (r * 255.0 * 256.0 * 256.0 + g * 255.0 * 256.0 + b * 255.0) * 0.1; - h = h / 20 - 127600; + let h = (r * 255.0 * 256.0 * 256.0 + g * 255.0 * 256.0 + b * 255.0) * 0.1; + h = h / 200 - 12750; h = Math.max(0, h); return h; }, diff --git a/site/docs/api/other/plane.zh.md b/site/docs/api/other/plane.zh.md index ba7d413abcc..30cfd9d7c03 100644 --- a/site/docs/api/other/plane.zh.md +++ b/site/docs/api/other/plane.zh.md @@ -50,8 +50,8 @@ const layer = new GeometryLayer().shape('plane').style({ terrainTexture: 'https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*eYFaRYlnnOUAAAAAAAAAAAAAARQnAQ', rgb2height: (r, g, b) => { - let h = -10000.0 + (r * 255.0 * 256.0 * 256.0 + g * 255.0 * 256.0 + b * 255.0) * 0.1; - h = h / 20 - 127600; + let h = (r * 255.0 * 256.0 * 256.0 + g * 255.0 * 256.0 + b * 255.0) * 0.1; + h = h / 200 - 12750; h = Math.max(0, h); return h; }, diff --git a/site/docs/api/other/sprite.en.md b/site/docs/api/other/sprite.en.md index 0cfaa617b29..1b39dc79f1e 100644 --- a/site/docs/api/other/sprite.en.md +++ b/site/docs/api/other/sprite.en.md @@ -24,8 +24,8 @@ let layer = new GeometryLayer() center: [120, 30], spriteCount: 120, spriteRadius: 10, - spriteTop: 2500000, - spriteUpdate: 20000, + spriteTop: 300, + spriteUpdate: 10, spriteScale: 0.6, }); ``` @@ -65,13 +65,11 @@ The number of particles generated by the layer, default is 100. #### spriteTop: number -The height range of particle movement, the default is 5000000.\ -🌟 It should be noted that under different map basemaps, the parameter values ​​of spriteTop/spriteUpdate need to be adjusted to achieve better results. The default value is adjusted on the AMap 1.0 map. +The height range of particle movement, the default is 300. #### spriteUpdate: number -The step size of particle motion refresh, expressed as motion speed, default is 10000.\ -🌟 It should be noted that under different map basemaps, the parameter values ​​of spriteTop/spriteUpdate need to be adjusted to achieve better results. The default value is adjusted on the AMap 1.0 map. +The step size of particle motion refresh, expressed as motion speed, default is 10. #### spriteScale: number diff --git a/site/docs/api/other/sprite.zh.md b/site/docs/api/other/sprite.zh.md index b21b08e492b..5252c4702b0 100644 --- a/site/docs/api/other/sprite.zh.md +++ b/site/docs/api/other/sprite.zh.md @@ -24,8 +24,8 @@ let layer = new GeometryLayer() center: [120, 30], spriteCount: 120, spriteRadius: 10, - spriteTop: 2500000, - spriteUpdate: 20000, + spriteTop: 300, + spriteUpdate: 10, spriteScale: 0.6, }); ``` @@ -65,13 +65,11 @@ SpriteGeometry 主要通过 style 方法设置位置、大小以及其他属性 #### spriteTop: number -粒子运动的高度范围,默认为 5000000. -🌟 需要注意的是,在不同的地图底图下,spriteTop/spriteUpdate 的参数值需要进行调整,才能得到较好的效果。默认值是在高德 1.0 的地图上调整的。 +粒子运动的高度范围,默认为 300. #### spriteUpdate: number -粒子运动刷新的步长,表现为运动速度、默认为 10000。 -🌟 需要注意的是,在不同的地图底图下,spriteTop/spriteUpdate 的参数值需要进行调整,才能得到较好的效果。默认值是在高德 1.0 的地图上调整的。 +粒子运动刷新的步长,表现为运动速度、默认为 10。 #### spriteScale: number diff --git a/site/examples/geometry/geometry/demo/rain.js b/site/examples/geometry/geometry/demo/rain.js index 7d9791ec186..ac60e90fb18 100644 --- a/site/examples/geometry/geometry/demo/rain.js +++ b/site/examples/geometry/geometry/demo/rain.js @@ -22,9 +22,9 @@ scene.on('loaded', () => { center: [120, 30], spriteCount: 120, spriteRadius: 10, - spriteTop: 2500000, - spriteUpdate: 20000, - spriteScale: 0.6, + spriteTop: 400, + spriteUpdate: 10, + spriteScale: 0.8, }); scene.addLayer(layer); }); diff --git a/site/examples/geometry/geometry/demo/snow.js b/site/examples/geometry/geometry/demo/snow.js index 23bc9c3e80d..62d76075311 100644 --- a/site/examples/geometry/geometry/demo/snow.js +++ b/site/examples/geometry/geometry/demo/snow.js @@ -21,7 +21,8 @@ scene.on('loaded', () => { center: [120, 30], spriteCount: 60, spriteRadius: 10, - spriteTop: 2500000, + spriteTop: 300, + spriteUpdate: 5, }); scene.addLayer(layer); }); diff --git a/site/examples/geometry/geometry/demo/terrain.js b/site/examples/geometry/geometry/demo/terrain.js index 14864f0468e..70a60c485ac 100644 --- a/site/examples/geometry/geometry/demo/terrain.js +++ b/site/examples/geometry/geometry/demo/terrain.js @@ -27,8 +27,8 @@ scene.on('loaded', () => { terrainTexture: 'https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*eYFaRYlnnOUAAAAAAAAAAAAAARQnAQ', rgb2height: (r, g, b) => { - let h = -10000.0 + (r * 255.0 * 256.0 * 256.0 + g * 255.0 * 256.0 + b * 255.0) * 0.1; - h = h / 20 - 127600; + let h = (r * 255.0 * 256.0 * 256.0 + g * 255.0 * 256.0 + b * 255.0) * 0.1; + h = h / 200 - 12750; h = Math.max(0, h); return h; }, @@ -40,24 +40,24 @@ scene.on('loaded', () => { modelData100; layer.on('terrainImageLoaded', () => { - modelData10 = layer.createModelData([], { + modelData10 = layer.layerModel.createModelData({ widthSegments: 10, heightSegments: 10, }); - modelData20 = layer.createModelData([], { + modelData20 = layer.layerModel.createModelData({ widthSegments: 20, heightSegments: 20, }); - modelData100 = layer.createModelData([], { + modelData100 = layer.layerModel.createModelData({ widthSegments: 100, heightSegments: 100, }); }); - scene.on('zoom', ({ value }) => { - const zoom = Math.floor(value); + scene.on('zoom', () => { + const zoom = Math.floor(scene.getZoom()); if (currentZoom !== zoom) { if (zoom > 13) { if (currentModelData !== '100x100') { @@ -77,6 +77,5 @@ scene.on('loaded', () => { } currentZoom = zoom; } - return ''; }); });