🌧️ Kesilmiş hassasiyet Her çokgen, sorguladığınız dairesel alana önceden kırpılmıştır — tarafınızda ek işlem gerekmez.
⚡ İkili verimlilik Protobuf kodlaması, JSON’a kıyasla yük boyutunu önemli ölçüde azaltır; mobil ve gömülü istemciler için idealdir.
🗺️ GeoJSON'a hazır Ham baytlardan geojson.io veya Mapbox’a doğrudan atabileceğiniz şekillere ulaşmak için yalnızca iki adım yeterlidir.
Endpoint ne döndürür?
POST /api/precipitations/geometry, ham ikili gövde (Content-Type: application/x-protobuf) ile yanıt verir.
Baytlar bir PrecipitationFeatureCollection mesajını kodlar; her biri kırpılmış bir MultiPolygon geometrisi ve tiplendirilmiş yağış özellikleri taşıyan PrecipitationFeature öğelerinin listesidir.
Yanıt gövdesini JSON veya metin olarak ayrıştırmayın . Protobuf ikili akışıdır; metin olarak işlenirse anlamsız karakterler görürsünüz.
Proto şeması 📄
Aşağıda iklim.co’nun bu endpoint için kullandığı proto mesaj tanımları verilmiştir.
// Paylaşılan geometri primitifleri
message Coordinate {
double lng = 1 ;
double lat = 2 ;
}
message Ring {
repeated Coordinate coordinates = 1 ;
}
message PolygonShape {
repeated Ring rings = 1 ;
}
message MultiPolygonShape {
repeated PolygonShape polygons = 1 ;
}
message Geometry {
enum GeometryType {
POINT = 0 ;
LINE_STRING = 1 ;
POLYGON = 2 ;
MULTI_POINT = 3 ;
MULTI_LINE_STRING = 4 ;
MULTI_POLYGON = 5 ;
GEOMETRY_COLLECTION = 6 ;
}
GeometryType type = 1 ;
oneof shape {
Coordinate point = 2 ;
LineStringShape line_string = 3 ;
PolygonShape polygon = 4 ;
MultiPointShape multi_point = 5 ;
MultiLineStringShape multi_line_string = 6 ;
MultiPolygonShape multi_polygon = 7 ;
GeometryCollectionShape geometry_collection = 8 ;
}
}
// Yağışa özgü mesajlar
message PrecipitationProperties {
string intensity = 1 ; // örn. "DRIZZLE", "LIGHT", "MODERATE"
int64 radar_timestamp = 2 ; // epoch milisaniye
bool forecast = 3 ; // true = NWP (Sayısal Hava Tahmini) tahmini, false = radar gözlemi
}
message PrecipitationFeature {
string id = 1 ;
Geometry geometry = 2 ;
PrecipitationProperties properties = 3 ;
}
message PrecipitationFeatureCollection {
repeated PrecipitationFeature features = 1 ;
}
Aşağıdaki çözümleme adımlarını çalıştırmadan önce geojson.proto dosyasının tamamını projenize kopyalayın. protobufjs yükleyicisi bu dosyaya çalışma zamanında ihtiyaç duyar.
Çözümleme ve GeoJSON’a dönüştürme 🛠️
Neden iki adım gerekli? GeoJSON bir JSON metin formatıdır (RFC 7946) ve resmi bir protobuf şeması yoktur. Koordinatları düz iç içe dizilerden ([[lng, lat], ...]) oluşur; protobuf ise isimsiz wrapper olmadan bu yapıyı temsil edemez. iklim.co’nun ikili şeması (Coordinate, Ring, PolygonShape, …) boyut verimliliği için tiplendirilmiş mesajlar kullandığından, çözümlemeden sonra her zaman bir yapısal dönüşüm adımı gerekir.
Adım adım kılavuz 🪜
Tek parça snippet ⚡
GeoJSON çıktısı 📋
protobufjs kurulumu 📦
npm install protobufjs
# veya
yarn add protobufjs
İkili yanıtı getir 🌐
fetch’e yanıtı ArrayBuffer olarak okumasını söyleyin, ardından proto çözümleyici için Uint8Array’e sarın.const response = await fetch ( "/api/precipitations/geometry" , {
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
"Authorization" : "Bearer <token>"
},
body: JSON . stringify ({
eventIds: [ "69baa6b76e0fe76a1957273f" , "4a1c3e9d8f2b07e5c6d4a1b2" ],
center: { lat: 36.80 , lng: 32.33 },
radius: 25000
})
});
const buffer = await response . arrayBuffer ();
const bytes = new Uint8Array ( buffer );
Protobuf baytlarını çözümle 🔓
geojson.proto dosyasını yükleyin ve baytları JavaScript nesnesine dönüştürün.import protobuf from "protobufjs" ;
const root = await protobuf . load ( "geojson.proto" );
const PrecipitationFeatureCollection = root . lookupType (
"PrecipitationFeatureCollection"
);
const fc = PrecipitationFeatureCollection . decode ( bytes );
Bu noktada fc şu şekilde görünür: {
"features" : [{
"id" : "69baa6b76e0fe76a1957273f" ,
"geometry" : {
"type" : "MULTI_POLYGON" ,
"multiPolygon" : {
"polygons" : [{
"rings" : [{
"coordinates" : [
{ "lng" : 32.33 , "lat" : 36.80 },
{ "lng" : 32.34 , "lat" : 36.81 }
]
}]
}]
}
},
"properties" : {
"intensity" : "DRIZZLE" ,
"radarTimestamp" : 1773846900000 ,
"forecast" : true
}
}]
}
Standart GeoJSON'a dönüştür 🗺️
Çözümlenen nesneyi RFC 7946 uyumlu GeoJSON’a dönüştürün. function toGeoJson ( fc ) {
return {
type: "FeatureCollection" ,
features: fc . features . map ( feature => ({
type: "Feature" ,
id: feature . id ,
geometry: {
type: "MultiPolygon" ,
coordinates: feature . geometry . multiPolygon . polygons . map ( polygon =>
polygon . rings . map ( ring =>
ring . coordinates . map ( coord => [ coord . lng , coord . lat ])
)
)
},
properties: {
intensity: feature . properties . intensity ,
radarTimestamp: feature . properties . radarTimestamp ,
forecast: feature . properties . forecast
}
}))
};
}
const geoJson = toGeoJson ( fc );
console . log ( JSON . stringify ( geoJson , null , 2 ));
Bu tek async fonksiyonu projenize ekleyin — fetch, çözümleme ve GeoJSON dönüşümünü uçtan uca yönetir. import protobuf from "protobufjs" ;
async function fetchPrecipitationGeoJson ({ eventIds , center , radius , token }) {
// 1 — İkili yanıtı getir
const response = await fetch ( "/api/precipitations/geometry" , {
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
"Authorization" : `Bearer ${ token } `
},
body: JSON . stringify ({ eventIds , center , radius })
});
if ( ! response . ok ) throw new Error ( `HTTP ${ response . status } ` );
const bytes = new Uint8Array ( await response . arrayBuffer ());
// 2 — Protobuf çözümle
const root = await protobuf . load ( "geojson.proto" );
const PrecipitationFeatureCollection = root . lookupType (
"PrecipitationFeatureCollection"
);
const fc = PrecipitationFeatureCollection . decode ( bytes );
// 3 — GeoJSON'a dönüştür
return {
type: "FeatureCollection" ,
features: fc . features . map ( f => ({
type: "Feature" ,
id: f . id ,
geometry: {
type: "MultiPolygon" ,
coordinates: f . geometry . multiPolygon . polygons . map ( poly =>
poly . rings . map ( ring =>
ring . coordinates . map ( c => [ c . lng , c . lat ])
)
)
},
properties: {
intensity: f . properties . intensity ,
radarTimestamp: f . properties . radarTimestamp ,
forecast: f . properties . forecast
}
}))
};
}
// Kullanım
const geoJson = await fetchPrecipitationGeoJson ({
eventIds: [ "69baa6b76e0fe76a1957273f" , "4a1c3e9d8f2b07e5c6d4a1b2" ],
center: { lat: 36.80 , lng: 32.33 },
radius: 25000 ,
token: "<token>"
});
Elde edilen GeoJSON nesnesi RFC 7946 uyumludur ve herhangi bir GeoJSON görüntüleyicide doğru şekilde işlenir. {
"type" : "FeatureCollection" ,
"features" : [
{
"type" : "Feature" ,
"id" : "69baa6b76e0fe76a1957273f" ,
"geometry" : {
"type" : "MultiPolygon" ,
"coordinates" : [
[
[
[ 32.33 , 36.80 ],
[ 32.34 , 36.81 ],
[ 32.35 , 36.80 ],
[ 32.33 , 36.80 ]
]
]
]
},
"properties" : {
"intensity" : "DRIZZLE" ,
"radarTimestamp" : 1773846900000 ,
"forecast" : true
}
}
]
}
🧪 Yukarıdaki çıktıyı kopyalayıp geojson.io adresine yapıştırarak harita entegrasyonunuza geçmeden önce geometrinizin doğru olup olmadığını görsel olarak doğrulayabilirsiniz.
Alan referansı 📚
PrecipitationFeature
Alan Tür Açıklama idstring Radar geometri kaydının benzersiz tanımlayıcısı. geometryobject Kırpılmış MultiPolygon geometrisi (aşağıya bakın). propertiesobject Tiplendirilmiş yağış meta verisi.
geometry (MultiPolygon)
Alan Yol Açıklama typegeometry.typeProto nesnesinde her zaman MULTI_POLYGON; GeoJSON’da "MultiPolygon" olur. polygonsgeometry.multiPolygon.polygons[]Çokgen dizisi. Her çokgenin bir veya daha fazla ring’i vardır. ringspolygons[].rings[]İlk ring dış sınırdır; ek ringler deliktir (iç halkalar). coordinatesrings[].coordinates[]{ lng, lat } nesnelerinin dizisi → GeoJSON için [lng, lat] dizilerine dönüştürün.
properties
Alan Tür Açıklama intensitystring Yağış yoğunluğu etiketi. Aşağıdaki IntensityType kataloğuna bakın. radarTimestampnumber Bu olayı tespit eden radar taramasının UTC epoch milisaniyesi. forecastboolean true = NWP (Sayısal Hava Tahmini) model tahmin çokgeni; false = canlı radar gözlemi.
IntensityType kataloğu
Değer Görünen ad Harita rengi DRIZZLEÇisenti #7ae1e8LIGHTHafif #00c8d8MODERATEOrta #2d7beaHEAVYŞiddetli #be46ebVERY_HEAVYÇok Şiddetli #e36546EXTREMEAşırı #ecd940