Posted in

使用 MapLibre 实现 Postgres 实时位置共享_AI阅读总结 — 包阅AI

包阅导读总结

1.

关键词:Postgres、Supabase、Realtime、Location、MapLibre

2.

总结:本教程基于 Postgis 和 Supabase 知识,介绍如何使用 Supabase 实时功能与 MapLibre 共享实时位置。包括创建捕获位置数据的 Telegram Bot 边缘函数,通过 RPC 向 Postgres 插入数据,利用 Supabase Realtime 监听数据库变化,在 React 中用 MapLibre GL JS 绘制实时位置数据。

3.

主要内容:

– 基础准备

– 基于之前对 Postgis 和 Supabase 的学习,添加 Supabase Realtime。

– 建议新手先回顾相关内容。

– 功能实现

– 创建捕获实时位置数据的 Telegram Bot 的 Edge Function,并插入数据到 Supabase。

– 使用 RPC 将位置数据插入 Postgres,RPC 在 Supabase Migrations 中定义。

– 用 Supabase Realtime 监听数据库变化,在 React 的 useEffect 钩子中设置订阅。

– 使用 react-map-gl 在地图上绘制位置标记,使用 Supabase Storage 上的 Protomaps 作为底图。

– 资源与拓展

– 提供创建 Telegram Bot 的详细指南链接。

– 给出相关代码在 GitHub 上的位置。

– 鼓励关注 Twitter 和 YouTube 频道以了解更多关于地图和 PostGIS 的内容。

思维导图:

文章地址:https://supabase.com/blog/postgres-realtime-location-sharing-with-maplibre

文章来源:supabase.com

作者:Supabase Blog

发布时间:2024/7/4 0:00

语言:英文

总字数:1132字

预计阅读时间:5分钟

评分:83分

标签:postgres,实时,地图


以下为原文内容

本内容来源于用户推荐转载,旨在分享知识与观点,如有侵权请联系删除 联系邮箱 media@ilingban.com

This tutorial is building upon the previous learnings on Postgis and Supabase and adding Supabase Realtime on top. If you’re new to this topic, we recommend you review the following first:

In this tutorial, you will learn to

  • Use a Supabase Edge Function to build a Telegram Bot that captures live location data.
  • Use an RPC (remote procedure call) to insert location data into Postgres from an Edge Function.
  • Use Supabase Realtime to listen to changes in the database.
  • Use MapLibre GL JS in React to draw live location data onto the map.

In this section, you will create an Edge Function that will capture live location data from a Telegram Bot. The Telegram Bot will send location data to the Edge Function, which will then insert the data into Supabase.

For a detailed guide on how to create a Telegram Bot, please refer to our docs here.

You can find the production ready code for the Telegram Bot Supabase Edge Function on GitHub. This is the relevant code that listens to the live location updates and writes them to the database:

/supabase/functions/telegram-bot/index.ts

_58

import { Database } from '../_shared/database.types.ts'

_58

const token = Deno.env.get('BOT_TOKEN')

_58

if (!token) throw new Error('BOT_TOKEN is unset')

_58

const supabase = createClient<Database>(

_58

Deno.env.get('SUPABASE_URL')!,

_58

Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!

_58

const bot = new Bot(token)

_58

bot.on('edit:location', async (ctx) => {

_58

from: { id: user_id },

_58

} = ctx.update.edited_message!

_58

const { error } = await supabase.rpc('location_insert', {

_58

_lat: location.latitude,

_58

_long: location.longitude,

_58

_timestamp: edit_date,

_58

'null value in column "event_id" of relation "locations" violates not-null constraint' &&

_58

error.message !== 'duplicate key value violates unique constraint "locations_pkey"'

_58

return console.log(`edit:location:insert:error:user:${user_id}: ${error.message}`)

_58

const handleUpdate = webhookCallback(bot, 'std/http')

_58

Deno.serve(async (req) => {

_58

const headers = req.headers

_58

const url = new URL(req.url)

_58

if (url.searchParams.get('secret') !== Deno.env.get('FUNCTION_SECRET')) {

_58

return new Response('not allowed', { status: 405 })

_58

return await handleUpdate(req)

_58

return new Response()

Use an RPC to insert location data into Postgres#

The edge function above uses an RPC (remote procedure call) to insert the location data into the database. The RPC is defined in our Supabase Migrations. The RPC first validates that the user has an active session and then inserts the location data into the locations table:

_10

CREATE OR REPLACE FUNCTION public.location_insert(_timestamp bigint, _lat double precision, _long double precision, _user_id bigint)

_10

declare active_event_id uuid;

_10

select event_id into active_event_id from public.sessions where user_id = _user_id and status = 'ACTIVE'::session_status;

_10

INSERT INTO public.locations(event_id, user_id, created_at, lat, long, location)

_10

VALUES (active_event_id, _user_id, to_timestamp(_timestamp), _lat, _long, st_point(_long, _lat));

_10

$$ LANGUAGE plpgsql VOLATILE;

In this section, you will use Supabase Realtime to listen to changes in the database. The Realtime API is a powerful tool that allows you to broadcast changes in the database to multiple clients.

The full client-side code for listening to the realtime changes and drawing the marker onto the map is available on GitHub.

We’re going to brake it down into a couple of steps:

Since we’re working in React, we will set up the Realtime subscription in the useEffect hook. If you’re using Next.js, it’s important to mark this with use client as we will need client-side JavaScript to make this happen:

/app/app/realtimemap/%5Bevent%5D/page.tsx

_41

export default function Page({ params }: { params: { event: string } }) {

_41

const supabase = createClient<Database>()

_41

const [locations, setLocations] = useState<{

_41

[key: string]: Tables<'locations'>

_41

const locationsRef = useRef<{

_41

[key: string]: Tables<'locations'>

_41

locationsRef.current = locations

_41

// Listen to realtime updates

_41

const subs = supabase

_41

.channel('schema-db-changes')

_41

event: 'INSERT', // Listen only to INSERTs

_41

filter: `event_id=eq.${params.event}`,

_41

const loc = payload.new as Tables<'locations'>

_41

...locationsRef.current,

_41

[loc.user_id.toString()]: loc,

_41

setLocations(updated)

_41

console.log('Subscribed')

The realtime subscription listener above updates the state of the locations object with the new location data, anytime it is inserted into the table. We can now use react-map-gl to easily draw the location markers onto the map:

/app/app/realtimemap/%5Bevent%5D/page.tsx

_33

cooperativeGestures={true}

_33

longitude: 103.852713,

_33

glyphs: 'https://cdn.protomaps.com/fonts/pbf/{fontstack}/{range}.pbf',

_33

'<a href="https://github.com/protomaps/basemaps">Protomaps</a> © <a href="https://openstreetmap.org">OpenStreetMap</a>',

_33

url: 'pmtiles://https://<project_ref>.supabase.co/functions/v1/maps-private/my_area.pmtiles',

_33

layers: layers('protomaps', 'light'),

_33

{Object.entries(locations).map(([key, value]) => (

_33

<Marker key={key} longitude={value.long} latitude={value.lat} color="red" />

Note that we’re using Protomaps hosted on Supabase Storage here for the base map. To learn about this read our previous tutorial here.

That’s it, this is how easy it is to add realtime location data to your applications using Supabase! We can’t wait to see what you will build!

Supabase Realtime is ideal for broadcasting location data to multiple clients. Combined with the power of PostGIS and the broader Postgres extension ecosystem, its’s a powerful solution for all your geospatial needs!

Want to learn more about Maps and PostGIS? Make sure to follow our Twitter and YouTube channels to not miss out! See you then!