NIP-44 Places

This commit is contained in:
arkinox 2023-12-06 12:17:59 -06:00 committed by arkin0x
parent 2bd4bf7841
commit 47633879eb
3 changed files with 167 additions and 0 deletions

163
44.md Normal file
View File

@ -0,0 +1,163 @@
NIP-44 Places
======
`draft` `optional`
A kind `37515` Place event represents a place on Earth.
Rationale
-----
This NIP provides a decentralized mechanism for people to publish places that matter to them on a map without any governing intermediaries such as Google Maps or OpenStreetMaps.
A Place event is cryptographically owned by its creator who has the sole ability to edit it.
Places can be zapped, reviewed, labeled, commented on, or shared like any other nostr event.
High quality places can be found by following pubkeys who publish them, reviews, [NIP-51 lists](/51.md), or even attached [NIP-13 proof-of-work](/13.md).
Properties of a Place may be defined by its creator, but may also be crowdsourced as discussed below, enabling a balance between ownership and open-source contribution.
> [!TIP]
> The 7515 in 37515 is alphanumeric code for GEO
### Good Use Cases
- If you own a business, you can truly own your place on the map by publishing a Place.
- Large facilities and campuses with many points of interest can group and share their Places by using a NIP-51 list called a [World](/51.md). Clients can use World lists to filter the Places on the map for focused experiences.
- Publish temporary points of interest like a speed trap or meetup location.
- Create a Place for each of your favorite camping spots or hiking paths.
- Create a list of your favorite bars for a pub crawl to share with others.
- Copy useful geo data from other sources to make it available on nostr.
### Bad Use Cases
- Replicating OpenStreetMaps data for every tree, river, road and municipality. This is background noise and should be handled in your client by tile services like Mapbox or OpenMapTiles.
- Publicizing your house. Don't publish places that put anyone's privacy at risk.
Place Event Structure
-----
A Place is comprised of two main parts: GeoJSON defines the geospatial structure of the Place in a standard format that can be displayed on a map, and `prop` tags enable the definition of properties for the Place that adhere to existing mapping standards while also enabling crowdsourcing of properties.
```javascript
{
kind: 37515,
content: '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"coordinates":[-63.704031143965054,27.04213619251243],"type":"Point"}}]}' // stringified JSON. Use https://geojson.io to easily create GeoJSON objects for testing.
tags: [
["d", "something unique"], // unique identifier for replaceable event
["L", "osm"], // specify usage of OpenStreetMaps namespace
["prop", "name", "Jitter's Coffee Shop", "osm"],
["prop", "opening_hours", "Mo-Fr_6:00-20:00,Sa-Su_6:00-17:00", "osm"],
["L", "schema/Place"], // specify usage of schema.org/Place namespace
["prop", "logo", "https://nostr.build/logo.png", "schema/Place"],
["admin", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"]
["admin", "f7234bd4c1394dda46d09f35bd384dd30cc552ad5541990f98844fb06676e9ca"]
["g", "dtee7"], // geohash of place; should be as accurate as possible
["g", "dtee"], // all less-precise geohashes must be defined to allow for searching -- see https://github.com/nostr-protocol/nips/pull/136#issuecomment-1788549584
["g", "dte"],
["g", "dt"],
["g", "d"],
],
pubkey: ...
created_at: ...
}
```
### Content
GeoJSON is used to define the Place's geospatial structure. This GeoJSON is stringified and stored in the `content` field of the event.
[geojson.io](https://geojson.io) is a great tool to play around with GeoJSON data structures on a map. It also validates them.
The `coordinates` property of the GeoJSON object will provide the [longitude, latitude] coordinate(s) to position the Place on a map.
> [!IMPORTANT]
> GeoJSON can contain multiple features, which means your Place may be a feature collection made up of multiple points or lines or polygons. Each feature can have its own `properties` object which may not be empty if the data is copied from somewhere else. However, the `properties` of a feature don't necessarily apply to the overall Place. Therefore, clients SHOULD NOT use the `properties` object as properties for the Place. See below for how to define properties that apply to the Place.
> If you have multiple features rich in properties, consider splitting them into separate Places.
### Prop Tags
A Place creator can describe the properties of their Place using `prop` tags which represent `key = value` pairs. Prop tags take the following form:
```json
"tags": [
["L", <namespace>]
["prop", <key>, <value>, <namespace>]
]
```
The `osm` [(Open Street Maps)](https://taginfo.openstreetmap.org/) and `schema/Place` [(schema.org/Place)](https://schema.org/Place) namespaces both provide extensive property lists that can be utilized in the prop tag for a Place. Other namespaces may be used as well. Clients can choose which keys/namespaces they support and provide auto-complete or property selection when creating a Place; they may also use the namespace as contextual information for how to interpret/display the prop.
#### Requirements
- The `"L"` tag MUST be present as specified in [NIP-32](https://github.com/nostr-protocol/nips/blob/master/32.md).
- The `key` and `value` SHOULD be defined in the referenced namespace.
- The last element in the prop tag MUST be a `namespace` defined in the `"L"` tag.
- Multiple `"prop"` tags MAY be used in a single event.
- Multiple `"L"` tags MAY be used in a single event, but each namespace MUST be referenced by at least 1 prop tag.
- `key` MUST not be empty.
- If `value` is empty, it denotes the complete removal of the property from the Place. This is NOT the same as using something like `false` as the value.
#### Using Props
Prop tags are __not__ indexed by relays. Props can be used for client-side filtering and interpretation of Places after they are queried from the relays; the `g` tag is the preferred method to query for Places in an area.
### Admin Tags
The Place creator can designate other pubkeys via `admin` tags. If these `admin` pubkeys publish kind `1754` events to apply properties to the Place, clients SHOULD give their props higher consideration than props applied by non-admin pubkeys.
### Other Tags
- `"d"` tag is necessary for a replaceable event if you desire to make more than one of them.
- `"g"` tag MUST be present and as accurate to the GeoJSON geometry as possible. This allows for indexed relay queries to retrieve Places in an area. Retrieving Places based on the geohash closest to the screen's viewport will be the primary method of retrieving Places from relays.
- `"expiration"` may be used for temporary Places such as marking a speed trap.
Prop Application Kind 1754
--------
A kind `1754` event MAY be used to apply props to other Places. This enables crowdsourcing of useful Place information, but clients ultimately decide how this information is used.
If a pubkey is listed in a Place's `"admin"` tag, clients SHOULD consider its `1754` events authoritative, but still subordinate to the Place's own prop tags.
### Content
The `content` field MAY include a human-readable explanation or note for the event.
### Prop Target
The prop event MUST include one or more `"a"` tags indicating
the target Places the props should be applied to.
### Examples
Crowdsourcing a prop for wheelchair accessibility to an existing Place using an OpenStreetMap (`osm`) tag:
```json
{
"kind": 1754,
"content": "Adding local observations regarding wheelchair accessibility at Jitter's Coffee Shop.",
"tags": [
["L", "osm"],
["prop", "access:wheelchair", "yes", "osm"]
["a", "37515:0af3b...:something unique"]
],
}
```
Implementations
--------
- https://go.yondar.me (work in progress)
Resources
---------
- https://geojson.io - useful playground for creating GeoJSON
- https://taginfo.openstreetmap.org - find Place props used in OpenStreetMaps
- https://schema.org/Place - find Place props defined in Schema
References
---------
- [NIP-32](/32.md)
- [NIP-51](/51.md)
- "NIP-85" https://github.com/nostr-protocol/nips/pull/879

1
51.md
View File

@ -44,6 +44,7 @@ Aside from their main identifier, the `"d"` tag, sets can optionally have a `"ti
| Relay sets | 30002 | user-defined relay groups the user can easily pick and choose from during various operations | `"relay"` (relay URLs) | | Relay sets | 30002 | user-defined relay groups the user can easily pick and choose from during various operations | `"relay"` (relay URLs) |
| Bookmark sets | 30003 | user-defined bookmarks categories , for when bookmarks must be in labeled separate groups | `"e"` (kind:1 notes), `"a"` (kind:30023 articles), `"t"` (hashtags), `"r" (URLs)` | | Bookmark sets | 30003 | user-defined bookmarks categories , for when bookmarks must be in labeled separate groups | `"e"` (kind:1 notes), `"a"` (kind:30023 articles), `"t"` (hashtags), `"r" (URLs)` |
| Curation sets | 30004 | groups of articles picked by users as interesting and/or belonging to the same category | `"a"` (kind:30023 articles), `"e"` (kind:1 notes) | | Curation sets | 30004 | groups of articles picked by users as interesting and/or belonging to the same category | `"a"` (kind:30023 articles), `"e"` (kind:1 notes) |
| Worlds | 30007 | groups of Places | `"a"` (kind:37515 Places) |
| Interest sets | 30015 | interest topics represented by a bunch of "hashtags" | `"t"` (hashtags) | | Interest sets | 30015 | interest topics represented by a bunch of "hashtags" | `"t"` (hashtags) |
| Emoji sets | 30030 | categorized emoji groups | `"emoji"` (see [NIP-30](30.md)) | | Emoji sets | 30030 | categorized emoji groups | `"emoji"` (see [NIP-30](30.md)) |

View File

@ -95,6 +95,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `1040` | OpenTimestamps | [03](03.md) | | `1040` | OpenTimestamps | [03](03.md) |
| `1063` | File Metadata | [94](94.md) | | `1063` | File Metadata | [94](94.md) |
| `1311` | Live Chat Message | [53](53.md) | | `1311` | Live Chat Message | [53](53.md) |
| `1754` | Prop Application | [44](/44.md) |
| `1971` | Problem Tracker | [nostrocket][nostrocket] | | `1971` | Problem Tracker | [nostrocket][nostrocket] |
| `1984` | Reporting | [56](56.md) | | `1984` | Reporting | [56](56.md) |
| `1985` | Label | [32](32.md) | | `1985` | Label | [32](32.md) |
@ -148,6 +149,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `31989` | Handler recommendation | [89](89.md) | | `31989` | Handler recommendation | [89](89.md) |
| `31990` | Handler information | [89](89.md) | | `31990` | Handler information | [89](89.md) |
| `34550` | Community Definition | [72](72.md) | | `34550` | Community Definition | [72](72.md) |
| `37515` | Place | [44](44.md) |
[nostrocket]: https://github.com/nostrocket/NIPS/blob/main/Problems.md [nostrocket]: https://github.com/nostrocket/NIPS/blob/main/Problems.md
[lnpub]: https://github.com/shocknet/Lightning.Pub/blob/master/proto/autogenerated/client.md [lnpub]: https://github.com/shocknet/Lightning.Pub/blob/master/proto/autogenerated/client.md
@ -214,6 +216,7 @@ Please update these lists when proposing NIPs introducing new event kinds.
| `nonce` | random | -- | [13](13.md) | | `nonce` | random | -- | [13](13.md) |
| `preimage` | hash of `bolt11` invoice | -- | [57](57.md) | | `preimage` | hash of `bolt11` invoice | -- | [57](57.md) |
| `price` | price | currency, frequency | [99](99.md) | | `price` | price | currency, frequency | [99](99.md) |
| `prop` | key | value, namespace | [44](/44.md) |
| `proxy` | external ID | protocol | [48](48.md) | | `proxy` | external ID | protocol | [48](48.md) |
| `published_at` | unix timestamp (string) | -- | [23](23.md) | | `published_at` | unix timestamp (string) | -- | [23](23.md) |
| `relay` | relay url | -- | [42](42.md) | | `relay` | relay url | -- | [42](42.md) |