惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cisco Talos Blog
Cisco Talos Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
爱范儿
爱范儿
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Jina AI
Jina AI
雷峰网
雷峰网
The Register - Security
The Register - Security
The Cloudflare Blog
博客园 - 【当耐特】
M
MIT News - Artificial intelligence
I
InfoQ
博客园 - 三生石上(FineUI控件)
H
Help Net Security
博客园 - 司徒正美
Vercel News
Vercel News
WordPress大学
WordPress大学
S
SegmentFault 最新的问题
云风的 BLOG
云风的 BLOG
B
Blog
Google DeepMind News
Google DeepMind News
B
Blog RSS Feed
L
LangChain Blog
人人都是产品经理
人人都是产品经理
GbyAI
GbyAI
T
The Blog of Author Tim Ferriss
T
Tailwind CSS Blog
aimingoo的专栏
aimingoo的专栏
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Recorded Future
Recorded Future
小众软件
小众软件
Martin Fowler
Martin Fowler
罗磊的独立博客
Stack Overflow Blog
Stack Overflow Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
酷 壳 – CoolShell
酷 壳 – CoolShell
腾讯CDC
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Apple Machine Learning Research
Apple Machine Learning Research
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - Franky
Hugging Face - Blog
Hugging Face - Blog
Y
Y Combinator Blog
V
Visual Studio Blog
F
Fortinet All Blogs
Microsoft Azure Blog
Microsoft Azure Blog
大猫的无限游戏
大猫的无限游戏
Engineering at Meta
Engineering at Meta
N
Netflix TechBlog - Medium
V
V2EX
Blog — PlanetScale
Blog — PlanetScale

Ember.js Blog

Ember 7.0 Released Announcing the Official TypeScript Types Public Preview Accessibility Working Group Update The 2020 Ember Roadmap Countdown to The New Year - Built-in Addons Countdown to The New Year - Ember Exam Countdown to The New Year - Ember Code Snippet Countdown to The New Year - Ember Changeset Countdown to The New Year - Ember In Viewport Countdown to The New Year - Ember CLI Update Countdown to The New Year - Ember Template Invocation Location Countdown to The New Year - Ember CLI TypeScript Countdown to The New Year - Ember Bootstrap and Ember Paper Countdown to The New Year - Ember CSS Modules Countdown to The New Year - Ember Shepherd Countdown to The New Year - Ember Template Lint Countdown to The New Year - Ember Composable Helpers Countdown to The New Year - Ember Leaflet Countdown to The New Year - Ember Intl Countdown to The New Year - Ember Test Selectors Countdown to The New Year - Ember Power Select Countdown to The New Year - Ember Simple Auth Countdown to The New Year - Ember SVG Jar Countdown to The New Year - Ember Page Title Countdown to The New Year- Ember A11Y Testing Countdown to The New Year - Ember Angle Brackets Codemod Countdown to The New Year - Ember CLI Sass Countdown to The New Year - Ember Animated Countdown to The New Year - Ember Auto Import Countdown to The New Year - Ember Concurrency Countdown to The New Year - Ember Tether Countdown to The New Year - Ember Modifier Countdown to The New Year - Ember CLI Mirage Countdown to The New Year - Ember Sortable Coming Soon in Ember Octane - Part 5: Glimmer Components Coming Soon in Ember Octane - Part 4: Modifiers Coming Soon in Ember Octane - Part 3: Tracked Properties Coming Soon in Ember Octane - Part 2: Angle Brackets & Named Arguments Preview Weekend: 2019 Ember Community Survey Coming Soon in Ember Octane - Part 1: Native Classes First Annual DecEmber Event! 2018 Ember Community Survey 2017 Ember Community Survey Announcing The Glimmer 2 Alpha Upcoming deprecation of baseURL in Ember CLI 2.7 2016 Ember Community Survey Announcing Ember Core Team Face to Face, January 2016 Ember.js 1.13.0 and 2.0 Beta Released Another Ember 2.x Status Update Ember.js 1.12 and 1.13 Beta (Glimmer!) Released Ember.js 1.11.1 Released Ember.js 1.11.0 and 1.12 Beta Released Ember.js 1.10.0 and 1.11 Beta Released Compiling templates with Ember 1.10 Core Team Meeting Minutes - 2014/08/01 Core Team Meeting Minutes - 2014/08/14 Core Team Meeting Minutes - 2014/09/12 Cleaning Up Github Issues Core Team Meeting Minutes - 2014/07/11 Core Team Meeting Minutes - 2014/07/25 Ember 1.6.0 and 1.7 Beta Released Core Team Meeting Minutes - 2014/06/13 Core Team Meeting Minutes - 2014/06/20 Core Team Meeting Minutes - 2014/06/27 Core Team Meeting Minutes - 2014/06/06 Core Team Meeting Minutes - 2014/04/25 Core Team Meeting Minutes - 2014/04/04 Ember 1.5.0 and 1.6 Beta Released Core Team Meeting Minutes - 2014/03/07 Core Team Meeting Minutes - 2014/03/14 Core Team Meeting Minutes - 2014/03/21 Core Team Meeting Minutes - 2014/02/28 Core Team Meeting Minutes - 2014/02/21 Core Team Meeting Minutes - 2014/02/14 Ember 1.4.0 and 1.5 Beta Released Core Team Meeting Minutes - 2014/01/27 Core Team Meeting Minutes - 2014/01/31 Core Team Meeting Minutes - 2014/02/07 Core Team Meeting Minutes - 2014/01/17 Core Team Meeting Minutes - 2014/01/03 Ember 1.3.0 and 1.4 Beta Released Core Team Meeting Minutes - 2013/12/20 Core Team Meeting Minutes - 2013/12/06 Ember 1.2.0 and 1.3 Beta Released Ember 1.1.2 Released Ember 1.1.1 and 1.2 Beta Released Ember 1.0 Released Ember 1.0 RC8 Released Ember 1.0 RC7 Released Ember 1.0 RC6.1, RC5.1, RC4.1, RC3.1, RC2.1 RC1.1 Released Ember 1.0 RC6 Ember 1.0 RC5 Ember 1.0 RC4 Ember 1.0 RC3 Announcing the Ember.js Security Policy Ember 1.0 RC2 Ember 1.0 RC Ember 1.0 Prerelease 2 Ember 1.0 Prerelease
Countdown to The New Year - Ember Mapbox GL
2019-12-21 · via Ember.js Blog

This is the 21st in our DecEmber series–"Countdown to The New Year: 31 Days of Ember Addons". We plan to highlight a new addon each day until the new year, and we hope you'll join us for the fun!

Day 21

Today we are going to take a look at making maps in Ember with ember-mapbox-gl.

What It Does

Have you ever wondered how to make maps in Ember? No? Okay, but you should!

This post is about adding an interactive map to your Ember project. By the end of this post, you'll have a map of the location of your company's business (provided that it has some physical location in Cartesian space).

(Note: I'm not talking about these kinds of maps, although they're not totally unrelated).

Every time I need to solve a problem in Ember, I do a quick search through the Ember addon ecosystem. Yes, it's satisfying to solve the problem yourself, but it's smarter—and quicker—to use someone else's code. Shoulders of giants, people. Now, web mapping is a pretty complicated suite of technologies, so the temptation to reinvent that wheel isn't as strong as, say, building your own file uploader.

A cursory glance at the available mapping addons show up a few options:

Am I missing any? Let me know. But I'm pretty confident these are the top mapping addons.

How do they work? They all have a one thing in common: declarative templating. Most of the mapping objects you see on screen are managed using template components and helper invocations:

<MapboxGl as |map|>
  <map.source
    @options=(hash type='geojson' data=(hash type='Point' coordinates=(array  -96.7969879, 32.7766642 ))) as |source|
  >
    <source.layer layer=(hash
      type='circle'
      paint=(hash
        circle-color='#007cbf'
        circle-radius=10)
      )
    >
  </map.source>
</MapboxGl>

This makes for a pretty nice experience, especially in terms of long-run maintainence because the visual aspects of your application correspond to a specific part of the template file.

(What would alternative be? I've seen some wild spaghetti monsters and they are not pleasant to deal with because they do not encapsulate lifecycle management).

I'm a little biased because I really only use ember-mapbox-gl. It's powered by WebGL. That means that the graphical output is powered by the things closer to the metal of the machine itself. Plus, mapbox-gl, the underlying library, is highly customizable. It might even be a little too customizable, and that's where ember-leaflet really shines: although it's SVG-based (read: not as fast), it provides more out-of-the-box abstractions at a higher level.

That said, for the sake of brevity, let's stick with ember-mapbox-gl. Once you become a mapping expert, you can make that call later.

Shut up and play the hits

Stop what you're doing right now, open the nearest Ember project, and type this into your terminal:

ember install ember-mapbox-gl

Great. It's installed. But here's the rub: you have to find a provider for the basemap itself, the underlying data showing streets, buildings, and points of interest. Because that data changes quite a lot, there's a lot of work that goes into maintaining it.

There are a few free and paid options out there, but for simplicity, let's use mapbox.com. Make an account there, and head over here to generate a public access token.

Open up your config/environment.js and add this:

'mapbox-gl': {
  accessToken: 'ACCESS TOKEN HERE',
  map: {
    style: 'mapbox://styles/mapbox/basic-v9',
    zoom: 13,
    center: [ -96.7969879, 32.7766642 ]
  }
},

You should swap out 'ACCESS TOKEN HERE' with the access token you generated on mapbox.com.

What are these other things? The map object here sets up the default state of the map when it loads. This means that when you create a map, it needs to know what to show, where to position the camera. This is overridable at template invocation time.

What is this style property? It's the reason we had to grab an API key from Mapbox: this points to the remote resource for loading all the basemap details you need to see for your users to orient themselves on the map. It tells your Mapbox map where to fetch all the roads and bridges and points of interest that fill a delightful, useful map.

Now, add this to one of your templates:

<MapboxGl as |map|>
  <map.source
    @options=(hash type='geojson' data=(hash type='Point' coordinates=(array  -96.7969879, 32.7766642 ))) as |source|
  >
    <source.layer layer=(hash
      type='circle'
      paint=(hash
        circle-color='#007cbf'
        circle-radius=10)
      )
    >
  </map.source>
</MapboxGl>

What is going on? Line by line:

<MapboxGl as |map|>

This instantiates a new map by creating new element in the DOM and binding the map instance to it.

<map.source
  @options=(hash type='geojson' data=(hash type='Point' coordinates=(array  -96.7969879, 32.7766642 ))) as |source|
>

This creates a mapbox-gl source, and passes options to it. What are those options? First, the type describes the kind of source that mapbox should use. What is a GeoJSON? It's a standard for representing geographic information in JSON. That explains the shape of the data property: a GeoJSON object specifies its own type. For our purposes, we're using a point:

For type "Point", the "coordinates" member is a single position.

That's a little far into the weeds, but it's worth mentioning because there actually is an underlying reason for these API choices.

Generally, you'll find that most of the components in ember-mapbox-gl correspond to the various mapbox-gl APIs. That means you can use the MapboxGL documentation site proper when using this addon

    <source.layer layer=(hash
      type='circle'
      paint=(hash
        circle-color='#007cbf'
        circle-radius=10)
      )
    >

Again, we're dealing with another area of the mapbox-gl API: the layer. Like GeoJSON, the shape of this object follows a styling specification. There are many ways to style a map layer.

One-by-one: source.layer invokes the addLayer method of mapbox-gl itself and passes some options. Those options—specifically, the layer property—adhere to the styling specification. Allowed options are type-specific, so there's no saying "this fill type should have a circle-radius of 1000". That doesn't make sense.

All together now

Here's a run-through of what we did:

  1. Install the addon
  2. Setup a Mapbox.com account and generate an API token
  3. Add your configuration to your config/environment.js
  4. Invoke your <MapboxGL> map and yield a block parameter
  5. Add a <map.source> inside the map block scope.
  6. Inside that block scope, add a <source.layer>

Why all this work? Because the addon is dealing with all the "gotchas" that come with lifecycle management. That means you can use these components as you would any other component:

{{#if this.someCondition}}
  <map.layer /> {{!-- show something !}}
{{/if}}

When the someCondition is truthy, it shows the layer. When it's falsey, it triggers the teardown methods inside mapbox-gl so things don't fall out of sync.

Much of ember-mapbox-gl is a bindings layer. It provides a declarative templating API for invoking parts of the mapbox-gl API proper. So, it's hands-off. But the price of customizability is having less of an opinion. As I mentioned earlier, that's where Ember Leaflet really shines, and I encourage you to look at that as well.

Note on map data providers

I'm a little disappointed by the dearth of free and open vector map data providers. That said, if you find that you would like to host your own map tile provider, check out OpenMapTiles. It's a free and open source server that hosts those tile URLs we were using at the beginning. My team uses it and have had no issues.

Thanks for reading! If you have any questions, please message me via the Ember Discord chat (Matt Gardner#6278). I'm more than happy to help!

Do you use this addons? Or any like them? We'd love to hear about Ember addons that bring you joy!