paint-brush
Bản đồ trên web bằng React và Mapboxtừ tác giả@rusanovn
1,365 lượt đọc
1,365 lượt đọc

Bản đồ trên web bằng React và Mapbox

từ tác giả Nikita Rusanov13m2024/02/01
Read on Terminal Reader

dài quá đọc không nổi

Tôi sẽ minh họa cách sử dụng Mapbox với React và giải thích cách các công nghệ này hoạt động cùng nhau.
featured image - Bản đồ trên web bằng React và Mapbox
Nikita Rusanov HackerNoon profile picture
0-item
1-item

Các ứng dụng web đã được hưởng lợi rất nhiều từ việc đưa vào bản đồ, cung cấp cho người dùng thông tin dựa trên vị trí có giá trị. Bản đồ đã thay đổi sự tương tác của chúng ta với thế giới, từ việc điều hướng những địa điểm xa lạ đến khám phá các quán ăn gần đó. Vì vậy, việc tích hợp bản đồ vào website ngày càng trở nên phổ biến trong thời gian gần đây. Tuy nhiên, việc thiết kế bản đồ vừa có chức năng vừa thân thiện với người dùng có thể là một thách thức, đặc biệt đối với những người thiếu kinh nghiệm trong lĩnh vực này. Trong bài viết này, tôi sẽ chia sẻ các mẹo hữu ích về cách tạo bản đồ hiệu quả trong trình duyệt của bạn.

ngăn xếp công nghệ

Hãy thảo luận về công nghệ. Khi làm việc với bản đồ, chúng tôi thường sử dụng ba lớp:

  • Hiển thị giao diện người dùng, bao gồm các nút và biểu mẫu. Trong ngăn xếp của chúng tôi, React thực hiện vai trò này;

  • Hiển thị bản đồ và cho phép tương tác người dùng. Chúng tôi sử dụng Mapbox cho việc này;

  • Tìm nạp dữ liệu từ máy chủ, chẳng hạn như thông tin về điểm đánh dấu hoặc đa giác. Để lấy dữ liệu, chúng tôi sử dụng tính năng tìm nạp tích hợp của trình duyệt.


Hãy xem xét từng mục để hiểu rõ hơn về nền tảng công nghệ của chúng tôi khi làm việc với bản đồ.

Phản ứng

Điểm đánh dấu và điều khiển bản đồ - đây là các thành phần React.


Các Phản ứng thư viện cho phép bạn làm việc với các thành phần trang một cách thuận tiện và hiệu quả. Nó được Facebook phát triển để sử dụng cho riêng họ và bao gồm nhiều thành phần như nút, biểu mẫu và các yếu tố tương tác khác trên trang. Ví dụ: Facebook đã tạo một thuật toán đối chiếu để nhanh chóng so sánh các trạng thái khác nhau.


Vì việc thay đổi các thành phần trên một trang là hoạt động tốn kém nhất đối với trình duyệt nên điều cần thiết là phải thực hiện việc đó một cách hiệu quả nhất có thể. Để giải quyết vấn đề này, các kỹ sư của Facebook đã phát triển thư viện React, cho phép thay đổi thành phần nhanh chóng và đơn giản trên một trang. Bên cạnh việc cung cấp các thay đổi trạng thái nhanh chóng trên một trang, React cho phép chúng ta thực hiện việc này một cách khai báo mà không cần làm việc trực tiếp với các phần tử DOM. Thay vào đó, chúng tôi sử dụng sự trừu tượng, thường là JSX , trông giống như HTML. Hãy xem xét một ví dụ:

 // It's our state. Is the user our friend or not? // false by default const [isFriend, setIsFriend] = useState(false) // Depending on the state, we show the text on the button const buttonText = isFriend ? 'Your my Friend' : 'Add as Friend' // There is JSX, syntax for UI // In this case, we display a button, when clicked, we change the state return ( <button onClick={() => setIsFriend(true)}>{buttonText}</button> )


Có thể lồng các thành phần với các thành phần DOM thông thường như biểu mẫu, nút và đầu vào ở cuối hệ thống phân cấp. Bằng cách tập hợp các phần tử đơn giản này, chúng ta có thể tạo ra những phần tử phức tạp hơn, chẳng hạn như một biểu mẫu hoàn chỉnh:

 const Form = () => ( <form> <input name="Email"/> <input name="Password"/> </form> ) const App = () => ( <main> <h1>My form!</h1> <Form /> </main> )


React hỗ trợ chúng ta như thế nào trong bối cảnh bản đồ? Vì bản đồ trên trang có tính tương tác, tương tự như nút hoặc biểu mẫu, nên chúng tôi mong muốn tối ưu hóa khả năng hiển thị và tương tác của nó thông qua các sự kiện như số lần nhấp chuột trên bản đồ. React có thể giúp đạt được sự tối ưu hóa này. Đây là một ví dụ về cách nó hoạt động:

 // Use React to render the map with different event handlers // and render markers return ( <BaseMap onInitMap={() => console.log('I am alive!')} onClickMap={() => console.log('Click!')} onDestroyMap={() => console.log('Oh no!')} > <ClustersMarkers /> <PostsMarkers /> <ListingsMarkers /> </BaseMap> )


Khi làm việc với React, điều cần thiết cần nhớ là nó cho phép thao tác hiệu quả các thành phần trên trang, thay đổi nhanh chóng và tương tác với chúng thông qua các sự kiện. Điều này đạt được thông qua sự trừu tượng hóa giống với HTML, giúp dễ dàng tạo các thành phần phức tạp từ những thành phần đơn giản hơn.

Hộp bản đồ

Mapbox cho phép chúng tôi hiển thị dữ liệu của riêng mình trên bản đồ.


Bây giờ, hãy thảo luận về bản đồ. Việc tạo và sử dụng bản đồ có thể là một thách thức và chỉ một số công ty sản xuất sản phẩm có thể thiết kế bản đồ từ đầu. Thông thường, hầu hết mọi người đều dựa vào các thư viện được tạo sẵn với API thân thiện với người dùng đã được thử và kiểm tra.


Có sẵn nhiều nhà cung cấp bản đồ động, bao gồm Google Maps, Tờ rơi, Bing Maps, Mapbox, v.v. Tuy nhiên, chúng tôi sẽ tập trung vào Hộp bản đồ do các tính năng mở rộng và chính sách giá cả hợp lý của nó. Ví dụ: Google Maps tính phí $700 để có được 100 nghìn lượt xem bản đồ mỗi tháng, trong khi Mapbox chỉ tính phí $250 . Hơn nữa, Mapbox cung cấp quyền truy cập miễn phí lên tới 50 nghìn lượt xem bản đồ mỗi tháng.


Ưu đãi của Mapbox Studio hộp bản đồ , một công cụ thường được so sánh với Photoshop cho bản đồ. Với công cụ này, các nhà thiết kế có thể tạo các kiểu tùy chỉnh, ẩn các phần tử bản đồ không cần thiết và xóa các phần hiển thị của ngôi nhà. Một trong những lợi ích của nó là khả năng nâng cao khả năng hiển thị của Điểm quan tâm . Một lợi thế khác là cơ hội thử nghiệm kiểu dáng bản đồ bằng màu sắc của công ty. Tuy nhiên, điều cần thiết là phải xem xét trải nghiệm người dùng và duy trì bảng màu quen thuộc, bao gồm cỏ xanh và nước xanh. Điểm hay nhất của Mapbox Studio là nó đơn giản hóa quy trình thiết kế bản đồ bằng cách loại bỏ nhu cầu phát triển và chuyển giao các yêu cầu, cuối cùng là giảm chi phí làm việc với bản đồ.


Ngoài ra, Mapbox còn cung cấp một công cụ mã hóa địa lý có thể chuyển đổi địa chỉ thành tọa độ hoặc ngược lại, đơn giản hóa quá trình định vị các điểm trên bản đồ. Tuy nhiên, công cụ của phạm vi phủ sóng trên toàn thế giới có thể không đủ, gây khó khăn cho một số dự án. Mapbox thu thập dữ liệu từ nhiều nguồn , chẳng hạn như các chính phủ, các sáng kiến dữ liệu mở như OpenStreetMap và các công ty tư nhân.


Examples of using Mapbox.

Mapbox cung cấp nhiều loại ví dụ thực tế , mặc dù tài liệu có thể được hưởng lợi từ một số cải tiến. Ví dụ: khi kết hợp chức năng đánh dấu, các ví dụ có thể mang lại nhiều thông tin hơn tài liệu. Ngoài ra, các thách thức có thể nảy sinh khi hợp nhất nhiều thành phần, chẳng hạn như cụm điểm đánh dấu, tải dữ liệu tùy chỉnh, chuẩn hóa và thay đổi trạng thái điểm đánh dấu.


Hãy xem lại bản đồ Mapbox. cái gì làm API hộp bản đồ LÀM?


  • Nó khởi tạo bản đồ trong một phần tử HTML trên trang;

  • Nó tải và hiển thị các hình ảnh tạo nên bản đồ;

  • Nó vẽ các phần tử bổ sung, chẳng hạn như điểm đánh dấu, sử dụng GeoJson làm dữ liệu đầu vào;

  • Nó tạo ra các sự kiện, chẳng hạn như các lần nhấp chuột hoặc thay đổi thu phóng, có thể được xử lý.


Chúng ta hãy xem xét kỹ hơn về từng mục này.


The map is divided into tiles (512x512).

Mapbox chuyên về hiển thị bản đồ bằng cách sử dụng các ô xếp. Các ô xếp là những hình ảnh vuông nhỏ tạo nên bản đồ lớn hơn. Kích thước mặc định của ô là 512x512 pixel và có thể là vectơ hoặc raster . Vectơ ô được sử dụng để hiển thị đường, tòa nhà, Điểm ưa thích (PoI), v.v. Chúng có thể được tạo kiểu động, nhẹ và cho phép tương tác mượt mà với bản đồ. Raster mặt khác, các ô xếp được sử dụng để hiển thị hình ảnh vệ tinh.


Xin lưu ý rằng Mapbox Studio cho phép chúng tôi chọn dữ liệu cụ thể mà chúng tôi muốn đưa vào các ô bản đồ. Những viên gạch này sau đó được đặt lên một Tranh sơn dầu , là một thành phần DOM đặc biệt trong trình duyệt hiển thị hình ảnh và các thành phần đồ họa khác trên web. Để bạn hình dung, nó tương tự như cách tài liệu được hiển thị trên canvas trong Google Docs.

 <canvas width="100" height="100" />


Mapbox xử lý việc tải, chèn và cập nhật các ô. Tất cả những gì chúng ta phải làm là chỉ định nơi chúng ta muốn hiển thị bản đồ và các điều kiện ban đầu, như mức thu phóng hoặc tọa độ của bản đồ. Để sử dụng Mapbox, bạn sẽ cần một truy cập thẻ , đây là khóa duy nhất có thể tìm thấy trong tài khoản Mapbox của bạn. Để thiết lập bản đồ cơ bản, đây là một ví dụ nhanh, nhưng để biết thêm thông tin, hãy xem liên kết cung cấp:

 mapboxgl.accessToken = 'YOUR_MAPBOX_ACCESS_TOKEN'; const map = new mapboxgl.Map({ container: 'map', // we can use an Id or an element style: 'mapbox://styles/mapbox/streets-v11', // URL for styles center: [-74.5, 40], // initial coordinates [lng, lat] zoom: 9, // initial zoom });


Sau này, chúng ta sẽ nhận được một bản đồ trên trang trong một phần tử có id 'map.'


Hiển thị bản đồ mà không có nội dung bổ sung.


Để cung cấp cho người dùng nhiều thông tin hơn trên bản đồ, chúng tôi thường hiển thị vị trí của một cơ sở nhất định hoặc ranh giới của một khu vực cụ thể. Để đạt được điều này, chúng tôi sử dụng một định dạng dữ liệu cụ thể được gọi là GeoJSON và hướng dẫn Mapbox cách hiển thị dữ liệu này.


GeoJSON là định dạng chuẩn để lưu trữ cấu trúc địa lý trên bản đồ. Nó có thể lưu trữ nhiều loại nguyên thủy khác nhau mô tả các đối tượng địa lý như địa chỉ, vị trí, đường phố, đường cao tốc, biên giới, quốc gia, tiểu bang và sự kết hợp của những đối tượng này, được gọi là nhiều phần. GeoJSON được giới thiệu vào năm 2008 và được thể hiện như thế này:

 { "type": "Feature", // also can be FeatureCollection, it's collection of Feature "geometry": { "type": "Point", // also can be LineString, Polygon, MultiPolygon "coordinates": [125.6, 10.1] // for other types you can use Array with coordinates }, "properties": { // it's metadata, we can you that to show something on the map "name": "Dinagat Islands" } }


Hãy nói về hệ tọa độ được sử dụng trong Mapbox. Theo mặc định, Mapbox sử dụng EPSG 3857 , đây là một cách chiếu Trái đất lên một bề mặt phẳng để làm việc với các viên gạch. Điều này được gọi là Web Mercator và là tiêu chuẩn cho bản đồ trực tuyến. Tuy nhiên, khi xử lý dữ liệu về điểm đánh dấu và đa giác, nó sử dụng một hệ tọa độ khác gọi là EPSG 4326 . Hệ thống này dựa vào vĩ độ và kinh độ để mô tả tọa độ trên hình elip của Trái đất. Mapbox và các nhà cung cấp bản đồ khác tự động chuyển đổi tọa độ từ EPSG 4326 sang EPSG 3857. Nếu chúng tôi cần làm việc với các phép chiếu , chúng ta có thể sử dụng phương thức map.setProjection .


Bây giờ, chúng ta sẽ thảo luận về cách hiển thị GeoJSON trên bản đồ. Mapbox cung cấp hai thực thể mà chúng tôi thấy hữu ích:

  • Nguồn - Đây là hạt giống dữ liệu. Ví dụ: chúng tôi có thể tạo một nguồn mới với dữ liệu GeoJSON và định cấu hình nó để tạo ID cho từng đối tượng địa lý trong bộ sưu tập đối tượng địa lý.

  • Lớp - Đây là cách biểu diễn dữ liệu. Chúng tôi có thể hiển thị dữ liệu từ nguồn theo nhiều cách khác nhau, chẳng hạn như hiển thị ranh giới.


Để hiển thị đa giác hoặc điểm đánh dấu trên bản đồ, chúng ta phải truy xuất dữ liệu ở định dạng GeoJson từ máy chủ. Sau đó, chúng tôi tạo một nguồn, nhập dữ liệu vào đó và kết nối nó với lớp được yêu cầu.

 const geoJsonFeature = { 'type': 'Feature', 'geometry': { 'type': 'Polygon', 'coordinates': [ [-67.13734, 45.13745], [-66.96466, 44.8097], [-68.03252, 44.3252], [-67.13734, 45.13745] ] } } // Create source with our data map.addSource('ourSource', { 'type': 'geojson', 'data': geoJsonFeature }); // Add layer for background map.addLayer({ 'id': 'background', 'type': 'fill', 'source': 'ourSource', // название нашего source 'layout': {}, 'paint': { 'fill-color': '#0080ff', 'fill-opacity': 0.5 } }); // Add layer for border map.addLayer({ 'id': 'border', 'type': 'line', 'source': 'ourSource', 'layout': {}, 'paint': { 'line-color': '#000', 'line-width': 3 } });


Sau khi chạy đoạn mã này, chúng ta nhận được kết quả:

Chúng tôi có thể hiển thị dữ liệu của riêng mình trên Mapbox.


Để tìm hiểu thêm về chủ đề này, bạn có thể tham khảo tài liệu được cung cấp bởi Mapbox. Trong hướng dẫn này, chúng tôi đã đề cập đến quá trình khởi tạo bản đồ và trình bày dữ liệu của chúng tôi. Tiếp theo, chúng ta sẽ khám phá cách xử lý các sự kiện như nhấp, kéo và thu phóng. Ví dụ: chúng ta có thể sử dụng Mapbox để theo dõi các sự kiện và hiển thị tọa độ trong bảng điều khiển khi người dùng di chuyển con trỏ trên bản đồ. Để đạt được điều này, chúng ta chỉ cần gọi phương thức on với loại sự kiện mà chúng ta muốn, tương tự như cách chúng ta làm việc với các phần tử DOM.

 map.on('mousemove', (e) => { console.log(JSON.stringify(e.point)); }); // Result: {"x":330,"y":49}


Tóm lại chúng ta cần nhớ điều gì? Mapbox cho phép chúng tôi hiển thị bản đồ, vẽ dữ liệu của chúng tôi lên trên bản đồ và xử lý các sự kiện trên bản đồ. Đồng thời, Mapbox đảm nhiệm việc tải và hiển thị hình ảnh (ô).

Tìm về

Tìm nạp cho phép chúng tôi tải dữ liệu cho bản đồ.


Một lời về tìm về . Chúng ta đã thấy cách hiển thị dữ liệu trên bản đồ, nhưng trước tiên, chúng ta phải truy xuất dữ liệu đó từ máy chủ. Khi chúng tôi tự động yêu cầu dữ liệu từ máy chủ ở chế độ nền mà không cần tải lại trang, chúng tôi gọi phương pháp này là AJAX (" JavaScript không đồng bộ XML "). Có nhiều công cụ để tải dữ liệu không đồng bộ từ máy chủ, chẳng hạn như Axios hoặc XMLHttpRequest (bản địa).


Cần nhớ điều gì? Chúng tôi truy xuất dữ liệu từ máy chủ và có nhiều thư viện cho việc này nhưng chúng tôi sẽ sử dụng tìm nạp. Tiếp theo, chúng ta sẽ xem xét cách chúng ta thực hiện điều này một cách cụ thể khi làm việc với bản đồ, vì có nhiều sắc thái khác nhau.

Phản ứng + Hộp bản đồ

Bây giờ hãy xem các công nghệ được mô tả ở trên phối hợp với nhau như thế nào. Đầu tiên, chúng ta sẽ truy xuất dữ liệu để hiển thị đa giác bằng cách tìm nạp. Sau đó, chúng tôi sẽ khai báo quá trình khởi tạo bản đồ và sau khi tải bản đồ, chúng tôi sẽ thêm đa giác vào bản đồ.


Bạn cũng có thể tìm thấy một ví dụ hoạt động tại liên kết cung cấp.

 const useFetch = () => { /* Our data { 'type': 'Feature', 'geometry': { 'type': 'Polygon', 'coordinates': [ [ [-67.13734, 45.13745], [-68.03252, 44.3252], [-68.90478, 47.18479], [-67.13734, 45.13745], ] ] } } */ const [data, setData] = useState(null) useEffect(() => { fetch('https://our-api.com/polygon') .then(response => response.json()) .then(setData) .catch(e => { console.error(e) }) }, [setData]) return { data } } const BaseMap = () => { // Use the hook to fetch data const { data } = useFetch(GET_REGION); // Map instance const map = useRef(null); // DOM element const mapContainer = useRef(null); // Main logic - init the map and add the event useEffect(() => { if (map.current) { return; // initialize map only once } mapboxgl.accessToken = 'YOUR_MAPBOX_ACCESS_TOKEN'; map.current = new mapboxgl.Map({ container: mapContainer.current, style: 'mapbox://styles/mapbox/light-v10', // style URL (it's Mapbox's core style) center: [-68.137343, 45.137451], // starting position zoom: 5 // starting zoom }); // Handle event map.on('load', () => { const sourceId = 'source-region' // Add a data source containing GeoJSON data map.addSource(sourceId, { 'type': 'geojson', 'data': data.region // our data from Apollo }); // Add a new layer to visualize the polygon map.addLayer({ 'id': 'background', 'type': 'fill', 'source': sourceId, // reference the data source 'paint': { 'fill-color': '#0080ff', // blue color fill 'fill-opacity': 0.5 } }); // Add a black outline around the polygon map.addLayer({ 'id': 'outline', 'type': 'line', 'source': sourceId, 'paint': { 'line-color': '#000', 'line-width': 3 } }); }); }); return <div ref={mapContainer} />; } 


Mapbox và React giúp bạn dễ dàng làm việc với bản đồ trên web.

Phần kết luận

Chúng tôi đã xem xét nền tảng công nghệ làm nền tảng cho kiến trúc tương lai của mình. Trong bài viết sau, chúng tôi sẽ thảo luận về các nguyên tắc giúp thiết kế kiến trúc bản đồ, cách đạt được độ ghép thấp và độ gắn kết cao tối đa của các mô-đun cũng như cách duy trì và phát triển hệ thống bản đồ có thể mở rộng.


Cảm ơn bạn rất nhiều sự chú ý của bạn! Có một ngày tuyệt vời.