1use std::ptr;
2
3pub(crate) use maplibre_core::style::{
4 GeoJsonSourceOptionsNativeExt, NativeGeoJsonSourceOptions, NativeTileSourceOptions,
5 NativeTileUrls, StyleImageOptionsNativeExt, TileSourceOptionsNativeExt,
6};
7pub use maplibre_core::{
8 GeoJsonSourceOptions, LocationIndicatorImageKind, RasterDemEncoding, SourceInfo, SourceType,
9 StyleImage, StyleImageInfo, StyleImageOptions, TileScheme, TileSourceOptions,
10 VectorTileEncoding,
11};
12use maplibre_native_core as maplibre_core;
13use maplibre_native_core::ptr::const_ptr_or_null;
14use maplibre_native_core::values::lat_lngs_to_native;
15use maplibre_native_sys as sys;
16
17use crate::custom_geometry::{CanonicalTileId, CustomGeometrySourceState};
18use crate::geojson::GeoJsonNativeExt;
19use crate::json::JsonValueNativeExt;
20use crate::render::PremultipliedRgba8Image;
21use crate::values::NativeValue;
22use crate::{
23 CustomGeometrySourceOptions, Error, ErrorKind, GeoJson, JsonValue, LatLng, LatLngBounds, Result,
24};
25
26impl super::MapHandle {
27 pub fn set_style_url(&self, url: &str) -> Result<()> {
37 let map = self.inner.as_ptr()?;
38 let url = maplibre_core::string::c_string(url)?;
39 maplibre_core::check(unsafe { sys::mln_map_set_style_url(map, url.as_ptr()) })?;
43 Ok(())
44 }
45
46 pub fn set_style_json(&self, json: &str) -> Result<()> {
57 let map = self.inner.as_ptr()?;
58 let json = maplibre_core::string::c_string(json)?;
59 maplibre_core::check(unsafe { sys::mln_map_set_style_json(map, json.as_ptr()) })?;
64 self.inner.clear_custom_geometry_sources();
65 Ok(())
66 }
67
68 pub fn add_custom_geometry_source(
77 &self,
78 source_id: &str,
79 options: CustomGeometrySourceOptions,
80 ) -> Result<()> {
81 let map = self.inner.as_ptr()?;
82 let source_id_view = maplibre_core::string::string_view(source_id);
83 let state = CustomGeometrySourceState::new(options);
84 let descriptor = state.descriptor();
85 maplibre_core::check(unsafe {
88 sys::mln_map_add_custom_geometry_source(map, source_id_view.raw(), &descriptor)
89 })?;
90 self.inner
91 .custom_geometry_sources
92 .borrow_mut()
93 .insert(source_id.to_owned(), state);
94 Ok(())
95 }
96
97 pub fn set_custom_geometry_source_tile_data(
99 &self,
100 source_id: &str,
101 tile_id: CanonicalTileId,
102 data: &GeoJson,
103 ) -> Result<()> {
104 let map = self.inner.as_ptr()?;
105 let source_id = maplibre_core::string::string_view(source_id);
106 let data = data.try_to_native()?;
107 maplibre_core::check(unsafe {
110 sys::mln_map_set_custom_geometry_source_tile_data(
111 map,
112 source_id.raw(),
113 tile_id.to_native(),
114 data.as_ptr(),
115 )
116 })
117 }
118
119 pub fn invalidate_custom_geometry_source_tile(
121 &self,
122 source_id: &str,
123 tile_id: CanonicalTileId,
124 ) -> Result<()> {
125 let map = self.inner.as_ptr()?;
126 let source_id = maplibre_core::string::string_view(source_id);
127 maplibre_core::check(unsafe {
130 sys::mln_map_invalidate_custom_geometry_source_tile(
131 map,
132 source_id.raw(),
133 tile_id.to_native(),
134 )
135 })
136 }
137
138 pub fn invalidate_custom_geometry_source_region(
140 &self,
141 source_id: &str,
142 bounds: LatLngBounds,
143 ) -> Result<()> {
144 let map = self.inner.as_ptr()?;
145 let source_id = maplibre_core::string::string_view(source_id);
146 maplibre_core::check(unsafe {
149 sys::mln_map_invalidate_custom_geometry_source_region(
150 map,
151 source_id.raw(),
152 bounds.to_native(),
153 )
154 })
155 }
156
157 pub fn add_style_source_json(&self, source_id: &str, source_json: &JsonValue) -> Result<()> {
159 let map = self.inner.as_ptr()?;
160 let source_id = maplibre_core::string::string_view(source_id);
161 let source_json = source_json.try_to_native()?;
162 maplibre_core::check(unsafe {
165 sys::mln_map_add_style_source_json(map, source_id.raw(), source_json.as_ptr())
166 })
167 }
168
169 pub fn add_vector_source_url(
171 &self,
172 source_id: &str,
173 url: &str,
174 options: Option<&TileSourceOptions>,
175 ) -> Result<()> {
176 let map = self.inner.as_ptr()?;
177 let source_id = maplibre_core::string::string_view(source_id);
178 let url = maplibre_core::string::string_view(url);
179 let options = options.map(TileSourceOptions::to_native);
180 let options_ptr = options
181 .as_ref()
182 .map_or(ptr::null(), NativeTileSourceOptions::as_ptr);
183 maplibre_core::check(unsafe {
186 sys::mln_map_add_vector_source_url(map, source_id.raw(), url.raw(), options_ptr)
187 })
188 }
189
190 pub fn add_vector_source_tiles<S: AsRef<str>>(
192 &self,
193 source_id: &str,
194 tiles: &[S],
195 options: Option<&TileSourceOptions>,
196 ) -> Result<()> {
197 let map = self.inner.as_ptr()?;
198 let source_id = maplibre_core::string::string_view(source_id);
199 let raw_tiles = NativeTileUrls::new(tiles);
200 let options = options.map(TileSourceOptions::to_native);
201 let options_ptr = options
202 .as_ref()
203 .map_or(ptr::null(), NativeTileSourceOptions::as_ptr);
204 maplibre_core::check(unsafe {
208 sys::mln_map_add_vector_source_tiles(
209 map,
210 source_id.raw(),
211 raw_tiles.as_ptr(),
212 raw_tiles.len(),
213 options_ptr,
214 )
215 })
216 }
217
218 pub fn add_raster_source_url(
220 &self,
221 source_id: &str,
222 url: &str,
223 options: Option<&TileSourceOptions>,
224 ) -> Result<()> {
225 let map = self.inner.as_ptr()?;
226 let source_id = maplibre_core::string::string_view(source_id);
227 let url = maplibre_core::string::string_view(url);
228 let options = options.map(TileSourceOptions::to_native);
229 let options_ptr = options
230 .as_ref()
231 .map_or(ptr::null(), NativeTileSourceOptions::as_ptr);
232 maplibre_core::check(unsafe {
235 sys::mln_map_add_raster_source_url(map, source_id.raw(), url.raw(), options_ptr)
236 })
237 }
238
239 pub fn add_raster_source_tiles<S: AsRef<str>>(
241 &self,
242 source_id: &str,
243 tiles: &[S],
244 options: Option<&TileSourceOptions>,
245 ) -> Result<()> {
246 let map = self.inner.as_ptr()?;
247 let source_id = maplibre_core::string::string_view(source_id);
248 let raw_tiles = NativeTileUrls::new(tiles);
249 let options = options.map(TileSourceOptions::to_native);
250 let options_ptr = options
251 .as_ref()
252 .map_or(ptr::null(), NativeTileSourceOptions::as_ptr);
253 maplibre_core::check(unsafe {
257 sys::mln_map_add_raster_source_tiles(
258 map,
259 source_id.raw(),
260 raw_tiles.as_ptr(),
261 raw_tiles.len(),
262 options_ptr,
263 )
264 })
265 }
266
267 pub fn add_raster_dem_source_url(
269 &self,
270 source_id: &str,
271 url: &str,
272 options: Option<&TileSourceOptions>,
273 ) -> Result<()> {
274 let map = self.inner.as_ptr()?;
275 let source_id = maplibre_core::string::string_view(source_id);
276 let url = maplibre_core::string::string_view(url);
277 let options = options.map(TileSourceOptions::to_native);
278 let options_ptr = options
279 .as_ref()
280 .map_or(ptr::null(), NativeTileSourceOptions::as_ptr);
281 maplibre_core::check(unsafe {
284 sys::mln_map_add_raster_dem_source_url(map, source_id.raw(), url.raw(), options_ptr)
285 })
286 }
287
288 pub fn add_raster_dem_source_tiles<S: AsRef<str>>(
290 &self,
291 source_id: &str,
292 tiles: &[S],
293 options: Option<&TileSourceOptions>,
294 ) -> Result<()> {
295 let map = self.inner.as_ptr()?;
296 let source_id = maplibre_core::string::string_view(source_id);
297 let raw_tiles = NativeTileUrls::new(tiles);
298 let options = options.map(TileSourceOptions::to_native);
299 let options_ptr = options
300 .as_ref()
301 .map_or(ptr::null(), NativeTileSourceOptions::as_ptr);
302 maplibre_core::check(unsafe {
306 sys::mln_map_add_raster_dem_source_tiles(
307 map,
308 source_id.raw(),
309 raw_tiles.as_ptr(),
310 raw_tiles.len(),
311 options_ptr,
312 )
313 })
314 }
315
316 pub fn add_image_source_url(
322 &self,
323 source_id: &str,
324 coordinates: &[LatLng; 4],
325 url: &str,
326 ) -> Result<()> {
327 let map = self.inner.as_ptr()?;
328 let source_id = maplibre_core::string::string_view(source_id);
329 let coordinates = lat_lngs_to_native(coordinates);
330 let url = maplibre_core::string::string_view(url);
331 maplibre_core::check(unsafe {
335 sys::mln_map_add_image_source_url(
336 map,
337 source_id.raw(),
338 const_ptr_or_null(&coordinates),
339 coordinates.len(),
340 url.raw(),
341 )
342 })
343 }
344
345 pub fn add_image_source_image(
351 &self,
352 source_id: &str,
353 coordinates: &[LatLng; 4],
354 image: &PremultipliedRgba8Image,
355 ) -> Result<()> {
356 let map = self.inner.as_ptr()?;
357 let source_id = maplibre_core::string::string_view(source_id);
358 let coordinates = lat_lngs_to_native(coordinates);
359 let image = maplibre_core::values::premultiplied_rgba8_image_to_native(image);
360 maplibre_core::check(unsafe {
364 sys::mln_map_add_image_source_image(
365 map,
366 source_id.raw(),
367 const_ptr_or_null(&coordinates),
368 coordinates.len(),
369 &image,
370 )
371 })
372 }
373
374 pub fn set_image_source_url(&self, source_id: &str, url: &str) -> Result<()> {
376 let map = self.inner.as_ptr()?;
377 let source_id = maplibre_core::string::string_view(source_id);
378 let url = maplibre_core::string::string_view(url);
379 maplibre_core::check(unsafe {
382 sys::mln_map_set_image_source_url(map, source_id.raw(), url.raw())
383 })
384 }
385
386 pub fn set_image_source_image(
388 &self,
389 source_id: &str,
390 image: &PremultipliedRgba8Image,
391 ) -> Result<()> {
392 let map = self.inner.as_ptr()?;
393 let source_id = maplibre_core::string::string_view(source_id);
394 let image = maplibre_core::values::premultiplied_rgba8_image_to_native(image);
395 maplibre_core::check(unsafe {
398 sys::mln_map_set_image_source_image(map, source_id.raw(), &image)
399 })
400 }
401
402 pub fn set_image_source_coordinates(
408 &self,
409 source_id: &str,
410 coordinates: &[LatLng; 4],
411 ) -> Result<()> {
412 let map = self.inner.as_ptr()?;
413 let source_id = maplibre_core::string::string_view(source_id);
414 let coordinates = lat_lngs_to_native(coordinates);
415 maplibre_core::check(unsafe {
419 sys::mln_map_set_image_source_coordinates(
420 map,
421 source_id.raw(),
422 const_ptr_or_null(&coordinates),
423 coordinates.len(),
424 )
425 })
426 }
427
428 pub fn image_source_coordinates(&self, source_id: &str) -> Result<Option<[LatLng; 4]>> {
430 let map = self.inner.as_ptr()?;
431 let source_id = maplibre_core::string::string_view(source_id);
432 let mut coordinates = [sys::mln_lat_lng {
433 latitude: 0.0,
434 longitude: 0.0,
435 }; 4];
436 let mut coordinate_count = 0;
437 let mut found = false;
438 maplibre_core::check(unsafe {
442 sys::mln_map_get_image_source_coordinates(
443 map,
444 source_id.raw(),
445 coordinates.as_mut_ptr(),
446 coordinates.len(),
447 &mut coordinate_count,
448 &mut found,
449 )
450 })?;
451 if !found {
452 return Ok(None);
453 }
454 if coordinate_count != coordinates.len() {
455 return Err(Error::new(
456 ErrorKind::NativeError,
457 None,
458 "native image source coordinate count did not match Rust image source invariant",
459 ));
460 }
461 Ok(Some(coordinates.map(LatLng::from_native)))
462 }
463
464 pub fn remove_style_source(&self, source_id: &str) -> Result<bool> {
469 let map = self.inner.as_ptr()?;
470 let source_id_key = source_id.to_owned();
471 let source_id = maplibre_core::string::string_view(source_id);
472 let mut removed = false;
473 maplibre_core::check(unsafe {
476 sys::mln_map_remove_style_source(map, source_id.raw(), &mut removed)
477 })?;
478 if removed {
479 self.inner
480 .custom_geometry_sources
481 .borrow_mut()
482 .remove(&source_id_key);
483 }
484 Ok(removed)
485 }
486
487 pub fn style_source_exists(&self, source_id: &str) -> Result<bool> {
489 let map = self.inner.as_ptr()?;
490 let source_id = maplibre_core::string::string_view(source_id);
491 let mut exists = false;
492 maplibre_core::check(unsafe {
495 sys::mln_map_style_source_exists(map, source_id.raw(), &mut exists)
496 })?;
497 Ok(exists)
498 }
499
500 pub fn set_style_image(
502 &self,
503 image_id: &str,
504 image: &PremultipliedRgba8Image,
505 options: Option<&StyleImageOptions>,
506 ) -> Result<()> {
507 let map = self.inner.as_ptr()?;
508 let image_id = maplibre_core::string::string_view(image_id);
509 let image = maplibre_core::values::premultiplied_rgba8_image_to_native(image);
510 let options = options.map(StyleImageOptions::to_native);
511 let options_ptr = options.as_ref().map_or(ptr::null(), ptr::from_ref);
512 maplibre_core::check(unsafe {
516 sys::mln_map_set_style_image(map, image_id.raw(), &image, options_ptr)
517 })
518 }
519
520 pub fn remove_style_image(&self, image_id: &str) -> Result<bool> {
524 let map = self.inner.as_ptr()?;
525 let image_id = maplibre_core::string::string_view(image_id);
526 let mut removed = false;
527 maplibre_core::check(unsafe {
530 sys::mln_map_remove_style_image(map, image_id.raw(), &mut removed)
531 })?;
532 Ok(removed)
533 }
534
535 pub fn style_image_exists(&self, image_id: &str) -> Result<bool> {
537 let map = self.inner.as_ptr()?;
538 let image_id = maplibre_core::string::string_view(image_id);
539 let mut exists = false;
540 maplibre_core::check(unsafe {
543 sys::mln_map_style_image_exists(map, image_id.raw(), &mut exists)
544 })?;
545 Ok(exists)
546 }
547
548 pub fn style_image_info(&self, image_id: &str) -> Result<Option<StyleImageInfo>> {
550 let map = self.inner.as_ptr()?;
551 let image_id = maplibre_core::string::string_view(image_id);
552 let mut info = maplibre_core::style::empty_style_image_info();
553 let mut found = false;
554 maplibre_core::check(unsafe {
558 sys::mln_map_get_style_image_info(map, image_id.raw(), &mut info, &mut found)
559 })?;
560 Ok(found.then(|| maplibre_core::values::style_image_info_from_native(&info)))
561 }
562
563 pub fn copy_style_image_premultiplied_rgba8(
565 &self,
566 image_id: &str,
567 ) -> Result<Option<StyleImage>> {
568 let map = self.inner.as_ptr()?;
569 let image_id = maplibre_core::string::string_view(image_id);
570 let mut raw_info = maplibre_core::style::empty_style_image_info();
571 let mut info_found = false;
572 maplibre_core::check(unsafe {
576 sys::mln_map_get_style_image_info(map, image_id.raw(), &mut raw_info, &mut info_found)
577 })?;
578 if !info_found {
579 return Ok(None);
580 }
581 let info = maplibre_core::values::style_image_info_from_native(&raw_info);
582
583 let mut data = vec![0u8; info.byte_length];
584 let mut copied_size = 0;
585 let mut found = false;
586 let pixels = if data.is_empty() {
587 ptr::null_mut()
588 } else {
589 data.as_mut_ptr()
590 };
591 maplibre_core::check(unsafe {
595 sys::mln_map_copy_style_image_premultiplied_rgba8(
596 map,
597 image_id.raw(),
598 pixels,
599 data.len(),
600 &mut copied_size,
601 &mut found,
602 )
603 })?;
604 if !found {
605 return Ok(None);
606 }
607 maplibre_core::style::style_image_from_copied_premultiplied_rgba8(info, data, copied_size)
608 .map(Some)
609 }
610
611 pub fn style_source_type(&self, source_id: &str) -> Result<Option<SourceType>> {
613 let map = self.inner.as_ptr()?;
614 let source_id = maplibre_core::string::string_view(source_id);
615 let mut raw_source_type = sys::MLN_STYLE_SOURCE_TYPE_UNKNOWN;
616 let mut found = false;
617 maplibre_core::check(unsafe {
620 sys::mln_map_get_style_source_type(
621 map,
622 source_id.raw(),
623 &mut raw_source_type,
624 &mut found,
625 )
626 })?;
627 Ok(found.then(|| SourceType::from_raw(raw_source_type)))
628 }
629
630 pub fn style_source_info(&self, source_id: &str) -> Result<Option<SourceInfo>> {
632 let map = self.inner.as_ptr()?;
633 let source_id = maplibre_core::string::string_view(source_id);
634 let mut info = maplibre_core::style::empty_style_source_info();
635 let mut found = false;
636 maplibre_core::check(unsafe {
640 sys::mln_map_get_style_source_info(map, source_id.raw(), &mut info, &mut found)
641 })?;
642 if !found {
643 return Ok(None);
644 }
645
646 let attribution = if info.has_attribution {
647 match self.copy_style_source_attribution(map, source_id.raw(), info.attribution_size)? {
648 Some(attribution) => Some(attribution),
649 None => return Ok(None),
650 }
651 } else {
652 None
653 };
654
655 Ok(Some(maplibre_core::style::style_source_info_from_native(
656 &info,
657 attribution,
658 )))
659 }
660
661 fn copy_style_source_attribution(
662 &self,
663 map: *mut sys::mln_map,
664 source_id: sys::mln_string_view,
665 attribution_size: usize,
666 ) -> Result<Option<String>> {
667 if attribution_size == 0 {
668 let mut copied_size = 0;
669 let mut found = false;
670 maplibre_core::check(unsafe {
674 sys::mln_map_copy_style_source_attribution(
675 map,
676 source_id,
677 ptr::null_mut(),
678 0,
679 &mut copied_size,
680 &mut found,
681 )
682 })?;
683 return Ok(found.then(String::new));
684 }
685
686 let mut buffer = vec![0u8; attribution_size];
687 let mut copied_size = 0;
688 let mut found = false;
689 maplibre_core::check(unsafe {
693 sys::mln_map_copy_style_source_attribution(
694 map,
695 source_id,
696 buffer.as_mut_ptr().cast(),
697 buffer.len(),
698 &mut copied_size,
699 &mut found,
700 )
701 })?;
702 if !found {
703 return Ok(None);
704 }
705 if copied_size > buffer.len() {
706 return Err(Error::new(
707 ErrorKind::NativeError,
708 None,
709 "native style source attribution size exceeded caller buffer",
710 ));
711 }
712 buffer.truncate(copied_size);
713 String::from_utf8(buffer).map(Some).map_err(|error| {
714 Error::invalid_argument(format!(
715 "native style source attribution was not valid UTF-8: {error}"
716 ))
717 })
718 }
719
720 pub fn add_geojson_source_url(
726 &self,
727 source_id: &str,
728 url: &str,
729 options: Option<&GeoJsonSourceOptions>,
730 ) -> Result<()> {
731 let map = self.inner.as_ptr()?;
732 let source_id = maplibre_core::string::string_view(source_id);
733 let url = maplibre_core::string::string_view(url);
734 let options = options
735 .map(GeoJsonSourceOptions::try_to_native)
736 .transpose()?;
737 let options_ptr = options
738 .as_ref()
739 .map_or(ptr::null(), NativeGeoJsonSourceOptions::as_ptr);
740 maplibre_core::check(unsafe {
744 sys::mln_map_add_geojson_source_url(map, source_id.raw(), url.raw(), options_ptr)
745 })
746 }
747
748 pub fn add_geojson_source_data(
754 &self,
755 source_id: &str,
756 data: &GeoJson,
757 options: Option<&GeoJsonSourceOptions>,
758 ) -> Result<()> {
759 let map = self.inner.as_ptr()?;
760 let source_id = maplibre_core::string::string_view(source_id);
761 let data = data.try_to_native()?;
762 let options = options
763 .map(GeoJsonSourceOptions::try_to_native)
764 .transpose()?;
765 let options_ptr = options
766 .as_ref()
767 .map_or(ptr::null(), NativeGeoJsonSourceOptions::as_ptr);
768 maplibre_core::check(unsafe {
772 sys::mln_map_add_geojson_source_data(map, source_id.raw(), data.as_ptr(), options_ptr)
773 })
774 }
775
776 pub fn set_geojson_source_url(&self, source_id: &str, url: &str) -> Result<()> {
780 let map = self.inner.as_ptr()?;
781 let source_id = maplibre_core::string::string_view(source_id);
782 let url = maplibre_core::string::string_view(url);
783 maplibre_core::check(unsafe {
785 sys::mln_map_set_geojson_source_url(map, source_id.raw(), url.raw())
786 })
787 }
788
789 pub fn set_geojson_source_data(&self, source_id: &str, data: &GeoJson) -> Result<()> {
793 let map = self.inner.as_ptr()?;
794 let source_id = maplibre_core::string::string_view(source_id);
795 let data = data.try_to_native()?;
796 maplibre_core::check(unsafe {
799 sys::mln_map_set_geojson_source_data(map, source_id.raw(), data.as_ptr())
800 })
801 }
802
803 pub fn add_style_layer_json(
805 &self,
806 layer_json: &JsonValue,
807 before_layer_id: Option<&str>,
808 ) -> Result<()> {
809 let map = self.inner.as_ptr()?;
810 let layer_json = layer_json.try_to_native()?;
811 let before_layer_id = maplibre_core::string::string_view(before_layer_id.unwrap_or(""));
812 maplibre_core::check(unsafe {
815 sys::mln_map_add_style_layer_json(map, layer_json.as_ptr(), before_layer_id.raw())
816 })
817 }
818
819 pub fn add_hillshade_layer(
821 &self,
822 layer_id: &str,
823 source_id: &str,
824 before_layer_id: Option<&str>,
825 ) -> Result<()> {
826 let map = self.inner.as_ptr()?;
827 let layer_id = maplibre_core::string::string_view(layer_id);
828 let source_id = maplibre_core::string::string_view(source_id);
829 let before_layer_id = maplibre_core::string::string_view(before_layer_id.unwrap_or(""));
830 maplibre_core::check(unsafe {
832 sys::mln_map_add_hillshade_layer(
833 map,
834 layer_id.raw(),
835 source_id.raw(),
836 before_layer_id.raw(),
837 )
838 })
839 }
840
841 pub fn add_color_relief_layer(
843 &self,
844 layer_id: &str,
845 source_id: &str,
846 before_layer_id: Option<&str>,
847 ) -> Result<()> {
848 let map = self.inner.as_ptr()?;
849 let layer_id = maplibre_core::string::string_view(layer_id);
850 let source_id = maplibre_core::string::string_view(source_id);
851 let before_layer_id = maplibre_core::string::string_view(before_layer_id.unwrap_or(""));
852 maplibre_core::check(unsafe {
854 sys::mln_map_add_color_relief_layer(
855 map,
856 layer_id.raw(),
857 source_id.raw(),
858 before_layer_id.raw(),
859 )
860 })
861 }
862
863 pub fn add_location_indicator_layer(
865 &self,
866 layer_id: &str,
867 before_layer_id: Option<&str>,
868 ) -> Result<()> {
869 let map = self.inner.as_ptr()?;
870 let layer_id = maplibre_core::string::string_view(layer_id);
871 let before_layer_id = maplibre_core::string::string_view(before_layer_id.unwrap_or(""));
872 maplibre_core::check(unsafe {
874 sys::mln_map_add_location_indicator_layer(map, layer_id.raw(), before_layer_id.raw())
875 })
876 }
877
878 pub fn set_location_indicator_location(
880 &self,
881 layer_id: &str,
882 coordinate: LatLng,
883 altitude: f64,
884 ) -> Result<()> {
885 let map = self.inner.as_ptr()?;
886 let layer_id = maplibre_core::string::string_view(layer_id);
887 maplibre_core::check(unsafe {
890 sys::mln_map_set_location_indicator_location(
891 map,
892 layer_id.raw(),
893 coordinate.to_native(),
894 altitude,
895 )
896 })
897 }
898
899 pub fn set_location_indicator_bearing(&self, layer_id: &str, bearing: f64) -> Result<()> {
901 let map = self.inner.as_ptr()?;
902 let layer_id = maplibre_core::string::string_view(layer_id);
903 maplibre_core::check(unsafe {
905 sys::mln_map_set_location_indicator_bearing(map, layer_id.raw(), bearing)
906 })
907 }
908
909 pub fn set_location_indicator_accuracy_radius(
911 &self,
912 layer_id: &str,
913 radius: f64,
914 ) -> Result<()> {
915 let map = self.inner.as_ptr()?;
916 let layer_id = maplibre_core::string::string_view(layer_id);
917 maplibre_core::check(unsafe {
919 sys::mln_map_set_location_indicator_accuracy_radius(map, layer_id.raw(), radius)
920 })
921 }
922
923 pub fn set_location_indicator_image_name(
925 &self,
926 layer_id: &str,
927 image_kind: LocationIndicatorImageKind,
928 image_id: &str,
929 ) -> Result<()> {
930 let map = self.inner.as_ptr()?;
931 let layer_id = maplibre_core::string::string_view(layer_id);
932 let image_id = maplibre_core::string::string_view(image_id);
933 maplibre_core::check(unsafe {
936 sys::mln_map_set_location_indicator_image_name(
937 map,
938 layer_id.raw(),
939 image_kind.raw_value(),
940 image_id.raw(),
941 )
942 })
943 }
944
945 pub fn style_layer_json(&self, layer_id: &str) -> Result<Option<JsonValue>> {
947 let map = self.inner.as_ptr()?;
948 let layer_id = maplibre_core::string::string_view(layer_id);
949 let mut out = maplibre_core::ptr::OutPtr::<sys::mln_json_snapshot>::new();
950 let mut found = false;
951 maplibre_core::check(unsafe {
954 sys::mln_map_get_style_layer_json(map, layer_id.raw(), out.as_mut_ptr(), &mut found)
955 })?;
956 let snapshot = unsafe { maplibre_core::json::copy_json_snapshot(out.into_option()) }?;
959 if found { Ok(snapshot) } else { Ok(None) }
960 }
961
962 pub fn set_style_light_json(&self, light_json: &JsonValue) -> Result<()> {
964 let map = self.inner.as_ptr()?;
965 let light_json = light_json.try_to_native()?;
966 maplibre_core::check(unsafe { sys::mln_map_set_style_light_json(map, light_json.as_ptr()) })
968 }
969
970 pub fn set_style_light_property(&self, property_name: &str, value: &JsonValue) -> Result<()> {
972 let map = self.inner.as_ptr()?;
973 let property_name = maplibre_core::string::string_view(property_name);
974 let value = value.try_to_native()?;
975 maplibre_core::check(unsafe {
978 sys::mln_map_set_style_light_property(map, property_name.raw(), value.as_ptr())
979 })
980 }
981
982 pub fn style_light_property(&self, property_name: &str) -> Result<Option<JsonValue>> {
984 let map = self.inner.as_ptr()?;
985 let property_name = maplibre_core::string::string_view(property_name);
986 let mut out = maplibre_core::ptr::OutPtr::<sys::mln_json_snapshot>::new();
987 maplibre_core::check(unsafe {
990 sys::mln_map_get_style_light_property(map, property_name.raw(), out.as_mut_ptr())
991 })?;
992 unsafe { maplibre_core::json::copy_json_snapshot(out.into_option()) }
995 }
996
997 pub fn set_layer_property(
999 &self,
1000 layer_id: &str,
1001 property_name: &str,
1002 value: &JsonValue,
1003 ) -> Result<()> {
1004 let map = self.inner.as_ptr()?;
1005 let layer_id = maplibre_core::string::string_view(layer_id);
1006 let property_name = maplibre_core::string::string_view(property_name);
1007 let value = value.try_to_native()?;
1008 maplibre_core::check(unsafe {
1011 sys::mln_map_set_layer_property(
1012 map,
1013 layer_id.raw(),
1014 property_name.raw(),
1015 value.as_ptr(),
1016 )
1017 })
1018 }
1019
1020 pub fn layer_property(&self, layer_id: &str, property_name: &str) -> Result<Option<JsonValue>> {
1022 let map = self.inner.as_ptr()?;
1023 let layer_id = maplibre_core::string::string_view(layer_id);
1024 let property_name = maplibre_core::string::string_view(property_name);
1025 let mut out = maplibre_core::ptr::OutPtr::<sys::mln_json_snapshot>::new();
1026 maplibre_core::check(unsafe {
1029 sys::mln_map_get_layer_property(
1030 map,
1031 layer_id.raw(),
1032 property_name.raw(),
1033 out.as_mut_ptr(),
1034 )
1035 })?;
1036 unsafe { maplibre_core::json::copy_json_snapshot(out.into_option()) }
1039 }
1040
1041 pub fn set_layer_filter(&self, layer_id: &str, filter: Option<&JsonValue>) -> Result<()> {
1043 let map = self.inner.as_ptr()?;
1044 let layer_id = maplibre_core::string::string_view(layer_id);
1045 let native_filter = filter.map(JsonValue::try_to_native).transpose()?;
1046 maplibre_core::check(unsafe {
1049 sys::mln_map_set_layer_filter(
1050 map,
1051 layer_id.raw(),
1052 native_filter
1053 .as_ref()
1054 .map_or(ptr::null(), |filter| filter.as_ptr()),
1055 )
1056 })
1057 }
1058
1059 pub fn layer_filter(&self, layer_id: &str) -> Result<Option<JsonValue>> {
1061 let map = self.inner.as_ptr()?;
1062 let layer_id = maplibre_core::string::string_view(layer_id);
1063 let mut out = maplibre_core::ptr::OutPtr::<sys::mln_json_snapshot>::new();
1064 maplibre_core::check(unsafe {
1067 sys::mln_map_get_layer_filter(map, layer_id.raw(), out.as_mut_ptr())
1068 })?;
1069 Ok(
1073 match unsafe { maplibre_core::json::copy_json_snapshot(out.into_option()) }? {
1074 Some(JsonValue::Null) => None,
1075 filter => filter,
1076 },
1077 )
1078 }
1079
1080 pub fn style_source_ids(&self) -> Result<Vec<String>> {
1082 let map = self.inner.as_ptr()?;
1083 let mut out = maplibre_core::ptr::OutPtr::<sys::mln_style_id_list>::new();
1084 maplibre_core::check(unsafe { sys::mln_map_list_style_source_ids(map, out.as_mut_ptr()) })?;
1088 unsafe { maplibre_core::style::copy_style_id_list(out.into_non_null("mln_style_id_list")?) }
1091 }
1092
1093 pub fn style_layer_ids(&self) -> Result<Vec<String>> {
1095 let map = self.inner.as_ptr()?;
1096 let mut out = maplibre_core::ptr::OutPtr::<sys::mln_style_id_list>::new();
1097 maplibre_core::check(unsafe { sys::mln_map_list_style_layer_ids(map, out.as_mut_ptr()) })?;
1101 unsafe { maplibre_core::style::copy_style_id_list(out.into_non_null("mln_style_id_list")?) }
1104 }
1105}