maplibre_native/render/
query.rs1use std::ptr;
2
3use maplibre_native_core as maplibre_core;
4use maplibre_native_sys as sys;
5
6use crate::Result;
7use crate::geojson::{Feature, FeatureNativeExt};
8use crate::json::{JsonValue, JsonValueNativeExt};
9
10pub use maplibre_core::query::{
11 FeatureExtensionResult, FeatureStateSelector, QueriedFeature, RenderedFeatureQueryOptions,
12 RenderedQueryGeometry, SourceFeatureQueryOptions,
13};
14pub(crate) use maplibre_core::query::{
15 FeatureStateSelectorNativeExt, NativeRenderedFeatureQueryOptions,
16 NativeSourceFeatureQueryOptions, RenderedFeatureQueryOptionsNativeExt,
17 RenderedQueryGeometryNativeExt, SourceFeatureQueryOptionsNativeExt,
18};
19
20impl super::RenderSessionHandle {
21 pub fn set_feature_state(
23 &self,
24 selector: &FeatureStateSelector,
25 state: &JsonValue,
26 ) -> Result<()> {
27 self.inner.ensure_no_frame_acquired()?;
28 let session = self.inner.as_ptr()?;
29 let selector = selector.to_native();
30 let state = state.try_to_native()?;
31 maplibre_core::check(unsafe {
34 sys::mln_render_session_set_feature_state(session, selector.as_ptr(), state.as_ptr())
35 })
36 }
37
38 pub fn get_feature_state(&self, selector: &FeatureStateSelector) -> Result<JsonValue> {
40 self.inner.ensure_no_frame_acquired()?;
41 let session = self.inner.as_ptr()?;
42 let selector = selector.to_native();
43 let mut out = maplibre_core::ptr::OutPtr::<sys::mln_json_snapshot>::new();
44 maplibre_core::check(unsafe {
47 sys::mln_render_session_get_feature_state(session, selector.as_ptr(), out.as_mut_ptr())
48 })?;
49 Ok(
52 unsafe { maplibre_core::json::copy_json_snapshot(out.into_option()) }?
53 .unwrap_or_else(|| JsonValue::Object(Vec::new())),
54 )
55 }
56
57 pub fn remove_feature_state(&self, selector: &FeatureStateSelector) -> Result<()> {
59 self.inner.ensure_no_frame_acquired()?;
60 let session = self.inner.as_ptr()?;
61 let selector = selector.to_native();
62 maplibre_core::check(unsafe {
65 sys::mln_render_session_remove_feature_state(session, selector.as_ptr())
66 })
67 }
68
69 pub fn query_rendered_features(
71 &self,
72 geometry: &RenderedQueryGeometry,
73 options: Option<&RenderedFeatureQueryOptions>,
74 ) -> Result<Vec<QueriedFeature>> {
75 self.inner.ensure_no_frame_acquired()?;
76 let session = self.inner.as_ptr()?;
77 let geometry = geometry.to_native();
78 let options = options
79 .map(RenderedFeatureQueryOptions::to_native)
80 .transpose()?;
81 let mut out = maplibre_core::ptr::OutPtr::<sys::mln_feature_query_result>::new();
82 maplibre_core::check(unsafe {
86 sys::mln_render_session_query_rendered_features(
87 session,
88 geometry.as_ptr(),
89 options
90 .as_ref()
91 .map_or(ptr::null(), NativeRenderedFeatureQueryOptions::as_ptr),
92 out.as_mut_ptr(),
93 )
94 })?;
95 unsafe {
98 maplibre_core::query::copy_feature_query_result(
99 out.into_non_null("mln_feature_query_result")?,
100 )
101 }
102 }
103
104 pub fn query_source_features(
106 &self,
107 source_id: &str,
108 options: Option<&SourceFeatureQueryOptions>,
109 ) -> Result<Vec<QueriedFeature>> {
110 self.inner.ensure_no_frame_acquired()?;
111 let session = self.inner.as_ptr()?;
112 let source_id = maplibre_core::string::string_view(source_id);
113 let options = options
114 .map(SourceFeatureQueryOptions::to_native)
115 .transpose()?;
116 let mut out = maplibre_core::ptr::OutPtr::<sys::mln_feature_query_result>::new();
117 maplibre_core::check(unsafe {
121 sys::mln_render_session_query_source_features(
122 session,
123 source_id.raw(),
124 options
125 .as_ref()
126 .map_or(ptr::null(), NativeSourceFeatureQueryOptions::as_ptr),
127 out.as_mut_ptr(),
128 )
129 })?;
130 unsafe {
133 maplibre_core::query::copy_feature_query_result(
134 out.into_non_null("mln_feature_query_result")?,
135 )
136 }
137 }
138
139 pub fn query_feature_extension(
141 &self,
142 source_id: &str,
143 feature: &Feature,
144 extension: &str,
145 extension_field: &str,
146 arguments: Option<&JsonValue>,
147 ) -> Result<FeatureExtensionResult> {
148 self.inner.ensure_no_frame_acquired()?;
149 let session = self.inner.as_ptr()?;
150 let source_id = maplibre_core::string::string_view(source_id);
151 let extension = maplibre_core::string::string_view(extension);
152 let extension_field = maplibre_core::string::string_view(extension_field);
153 let feature = feature.try_to_native(0)?;
154 if let Some(arguments) = arguments
155 && !matches!(arguments, JsonValue::Object(_))
156 {
157 return Err(crate::Error::invalid_argument(
158 "feature extension arguments must be a JSON object",
159 ));
160 }
161 let arguments = arguments.map(JsonValue::try_to_native).transpose()?;
162 let mut out = maplibre_core::ptr::OutPtr::<sys::mln_feature_extension_result>::new();
163 maplibre_core::check(unsafe {
167 sys::mln_render_session_query_feature_extensions(
168 session,
169 source_id.raw(),
170 feature.as_ptr(),
171 extension.raw(),
172 extension_field.raw(),
173 arguments
174 .as_ref()
175 .map_or(ptr::null(), crate::json::NativeJsonValue::as_ptr),
176 out.as_mut_ptr(),
177 )
178 })?;
179 unsafe {
182 maplibre_core::query::copy_feature_extension_result(
183 out.into_non_null("mln_feature_extension_result")?,
184 )
185 }
186 }
187}