1use std::ptr;
2
3pub(crate) use maplibre_core::style::{
4 NativeTileSourceOptions, NativeTileUrls, StyleImageOptionsNativeExt, TileSourceOptionsNativeExt,
5};
6pub use maplibre_core::{
7 LocationIndicatorImageKind, RasterDemEncoding, SourceInfo, SourceType, StyleImage,
8 StyleImageInfo, StyleImageOptions, TileScheme, TileSourceOptions, VectorTileEncoding,
9};
10use maplibre_native_core as maplibre_core;
11use maplibre_native_core::ptr::const_ptr_or_null;
12use maplibre_native_core::values::lat_lngs_to_native;
13use maplibre_native_sys as sys;
14
15use crate::custom_geometry::{CanonicalTileId, CustomGeometrySourceState};
16use crate::geojson::GeoJsonNativeExt;
17use crate::json::JsonValueNativeExt;
18use crate::render::PremultipliedRgba8Image;
19use crate::values::NativeValue;
20use crate::{
21 CustomGeometrySourceOptions, Error, ErrorKind, GeoJson, JsonValue, LatLng, LatLngBounds, Result,
22};
23
24impl super::MapHandle {
25 pub fn set_style_url(&self, url: &str) -> Result<()> {
28 let map = self.inner.as_ptr()?;
29 let url = maplibre_core::string::c_string(url)?;
30 maplibre_core::check(unsafe { sys::mln_map_set_style_url(map, url.as_ptr()) })?;
34 Ok(())
35 }
36
37 pub fn set_style_json(&self, json: &str) -> Result<()> {
39 let map = self.inner.as_ptr()?;
40 let json = maplibre_core::string::c_string(json)?;
41 maplibre_core::check(unsafe { sys::mln_map_set_style_json(map, json.as_ptr()) })?;
46 self.inner.clear_custom_geometry_sources();
47 Ok(())
48 }
49
50 pub fn add_custom_geometry_source(
59 &self,
60 source_id: &str,
61 options: CustomGeometrySourceOptions,
62 ) -> Result<()> {
63 let map = self.inner.as_ptr()?;
64 let source_id_view = maplibre_core::string::string_view(source_id);
65 let state = CustomGeometrySourceState::new(options);
66 let descriptor = state.descriptor();
67 maplibre_core::check(unsafe {
70 sys::mln_map_add_custom_geometry_source(map, source_id_view.raw(), &descriptor)
71 })?;
72 self.inner
73 .custom_geometry_sources
74 .borrow_mut()
75 .insert(source_id.to_owned(), state);
76 Ok(())
77 }
78
79 pub fn set_custom_geometry_source_tile_data(
81 &self,
82 source_id: &str,
83 tile_id: CanonicalTileId,
84 data: &GeoJson,
85 ) -> Result<()> {
86 let map = self.inner.as_ptr()?;
87 let source_id = maplibre_core::string::string_view(source_id);
88 let data = data.try_to_native()?;
89 maplibre_core::check(unsafe {
92 sys::mln_map_set_custom_geometry_source_tile_data(
93 map,
94 source_id.raw(),
95 tile_id.to_native(),
96 data.as_ptr(),
97 )
98 })
99 }
100
101 pub fn invalidate_custom_geometry_source_tile(
103 &self,
104 source_id: &str,
105 tile_id: CanonicalTileId,
106 ) -> Result<()> {
107 let map = self.inner.as_ptr()?;
108 let source_id = maplibre_core::string::string_view(source_id);
109 maplibre_core::check(unsafe {
112 sys::mln_map_invalidate_custom_geometry_source_tile(
113 map,
114 source_id.raw(),
115 tile_id.to_native(),
116 )
117 })
118 }
119
120 pub fn invalidate_custom_geometry_source_region(
122 &self,
123 source_id: &str,
124 bounds: LatLngBounds,
125 ) -> Result<()> {
126 let map = self.inner.as_ptr()?;
127 let source_id = maplibre_core::string::string_view(source_id);
128 maplibre_core::check(unsafe {
131 sys::mln_map_invalidate_custom_geometry_source_region(
132 map,
133 source_id.raw(),
134 bounds.to_native(),
135 )
136 })
137 }
138
139 pub fn add_style_source_json(&self, source_id: &str, source_json: &JsonValue) -> Result<()> {
141 let map = self.inner.as_ptr()?;
142 let source_id = maplibre_core::string::string_view(source_id);
143 let source_json = source_json.try_to_native()?;
144 maplibre_core::check(unsafe {
147 sys::mln_map_add_style_source_json(map, source_id.raw(), source_json.as_ptr())
148 })
149 }
150
151 pub fn add_vector_source_url(
153 &self,
154 source_id: &str,
155 url: &str,
156 options: Option<&TileSourceOptions>,
157 ) -> Result<()> {
158 let map = self.inner.as_ptr()?;
159 let source_id = maplibre_core::string::string_view(source_id);
160 let url = maplibre_core::string::string_view(url);
161 let options = options.map(TileSourceOptions::to_native);
162 let options_ptr = options
163 .as_ref()
164 .map_or(ptr::null(), NativeTileSourceOptions::as_ptr);
165 maplibre_core::check(unsafe {
168 sys::mln_map_add_vector_source_url(map, source_id.raw(), url.raw(), options_ptr)
169 })
170 }
171
172 pub fn add_vector_source_tiles<S: AsRef<str>>(
174 &self,
175 source_id: &str,
176 tiles: &[S],
177 options: Option<&TileSourceOptions>,
178 ) -> Result<()> {
179 let map = self.inner.as_ptr()?;
180 let source_id = maplibre_core::string::string_view(source_id);
181 let raw_tiles = NativeTileUrls::new(tiles);
182 let options = options.map(TileSourceOptions::to_native);
183 let options_ptr = options
184 .as_ref()
185 .map_or(ptr::null(), NativeTileSourceOptions::as_ptr);
186 maplibre_core::check(unsafe {
190 sys::mln_map_add_vector_source_tiles(
191 map,
192 source_id.raw(),
193 raw_tiles.as_ptr(),
194 raw_tiles.len(),
195 options_ptr,
196 )
197 })
198 }
199
200 pub fn add_raster_source_url(
202 &self,
203 source_id: &str,
204 url: &str,
205 options: Option<&TileSourceOptions>,
206 ) -> Result<()> {
207 let map = self.inner.as_ptr()?;
208 let source_id = maplibre_core::string::string_view(source_id);
209 let url = maplibre_core::string::string_view(url);
210 let options = options.map(TileSourceOptions::to_native);
211 let options_ptr = options
212 .as_ref()
213 .map_or(ptr::null(), NativeTileSourceOptions::as_ptr);
214 maplibre_core::check(unsafe {
217 sys::mln_map_add_raster_source_url(map, source_id.raw(), url.raw(), options_ptr)
218 })
219 }
220
221 pub fn add_raster_source_tiles<S: AsRef<str>>(
223 &self,
224 source_id: &str,
225 tiles: &[S],
226 options: Option<&TileSourceOptions>,
227 ) -> Result<()> {
228 let map = self.inner.as_ptr()?;
229 let source_id = maplibre_core::string::string_view(source_id);
230 let raw_tiles = NativeTileUrls::new(tiles);
231 let options = options.map(TileSourceOptions::to_native);
232 let options_ptr = options
233 .as_ref()
234 .map_or(ptr::null(), NativeTileSourceOptions::as_ptr);
235 maplibre_core::check(unsafe {
239 sys::mln_map_add_raster_source_tiles(
240 map,
241 source_id.raw(),
242 raw_tiles.as_ptr(),
243 raw_tiles.len(),
244 options_ptr,
245 )
246 })
247 }
248
249 pub fn add_raster_dem_source_url(
251 &self,
252 source_id: &str,
253 url: &str,
254 options: Option<&TileSourceOptions>,
255 ) -> Result<()> {
256 let map = self.inner.as_ptr()?;
257 let source_id = maplibre_core::string::string_view(source_id);
258 let url = maplibre_core::string::string_view(url);
259 let options = options.map(TileSourceOptions::to_native);
260 let options_ptr = options
261 .as_ref()
262 .map_or(ptr::null(), NativeTileSourceOptions::as_ptr);
263 maplibre_core::check(unsafe {
266 sys::mln_map_add_raster_dem_source_url(map, source_id.raw(), url.raw(), options_ptr)
267 })
268 }
269
270 pub fn add_raster_dem_source_tiles<S: AsRef<str>>(
272 &self,
273 source_id: &str,
274 tiles: &[S],
275 options: Option<&TileSourceOptions>,
276 ) -> Result<()> {
277 let map = self.inner.as_ptr()?;
278 let source_id = maplibre_core::string::string_view(source_id);
279 let raw_tiles = NativeTileUrls::new(tiles);
280 let options = options.map(TileSourceOptions::to_native);
281 let options_ptr = options
282 .as_ref()
283 .map_or(ptr::null(), NativeTileSourceOptions::as_ptr);
284 maplibre_core::check(unsafe {
288 sys::mln_map_add_raster_dem_source_tiles(
289 map,
290 source_id.raw(),
291 raw_tiles.as_ptr(),
292 raw_tiles.len(),
293 options_ptr,
294 )
295 })
296 }
297
298 pub fn add_image_source_url(
304 &self,
305 source_id: &str,
306 coordinates: &[LatLng; 4],
307 url: &str,
308 ) -> Result<()> {
309 let map = self.inner.as_ptr()?;
310 let source_id = maplibre_core::string::string_view(source_id);
311 let coordinates = lat_lngs_to_native(coordinates);
312 let url = maplibre_core::string::string_view(url);
313 maplibre_core::check(unsafe {
317 sys::mln_map_add_image_source_url(
318 map,
319 source_id.raw(),
320 const_ptr_or_null(&coordinates),
321 coordinates.len(),
322 url.raw(),
323 )
324 })
325 }
326
327 pub fn add_image_source_image(
333 &self,
334 source_id: &str,
335 coordinates: &[LatLng; 4],
336 image: &PremultipliedRgba8Image,
337 ) -> Result<()> {
338 let map = self.inner.as_ptr()?;
339 let source_id = maplibre_core::string::string_view(source_id);
340 let coordinates = lat_lngs_to_native(coordinates);
341 let image = maplibre_core::values::premultiplied_rgba8_image_to_native(image);
342 maplibre_core::check(unsafe {
346 sys::mln_map_add_image_source_image(
347 map,
348 source_id.raw(),
349 const_ptr_or_null(&coordinates),
350 coordinates.len(),
351 &image,
352 )
353 })
354 }
355
356 pub fn set_image_source_url(&self, source_id: &str, url: &str) -> Result<()> {
358 let map = self.inner.as_ptr()?;
359 let source_id = maplibre_core::string::string_view(source_id);
360 let url = maplibre_core::string::string_view(url);
361 maplibre_core::check(unsafe {
364 sys::mln_map_set_image_source_url(map, source_id.raw(), url.raw())
365 })
366 }
367
368 pub fn set_image_source_image(
370 &self,
371 source_id: &str,
372 image: &PremultipliedRgba8Image,
373 ) -> Result<()> {
374 let map = self.inner.as_ptr()?;
375 let source_id = maplibre_core::string::string_view(source_id);
376 let image = maplibre_core::values::premultiplied_rgba8_image_to_native(image);
377 maplibre_core::check(unsafe {
380 sys::mln_map_set_image_source_image(map, source_id.raw(), &image)
381 })
382 }
383
384 pub fn set_image_source_coordinates(
390 &self,
391 source_id: &str,
392 coordinates: &[LatLng; 4],
393 ) -> Result<()> {
394 let map = self.inner.as_ptr()?;
395 let source_id = maplibre_core::string::string_view(source_id);
396 let coordinates = lat_lngs_to_native(coordinates);
397 maplibre_core::check(unsafe {
401 sys::mln_map_set_image_source_coordinates(
402 map,
403 source_id.raw(),
404 const_ptr_or_null(&coordinates),
405 coordinates.len(),
406 )
407 })
408 }
409
410 pub fn image_source_coordinates(&self, source_id: &str) -> Result<Option<[LatLng; 4]>> {
412 let map = self.inner.as_ptr()?;
413 let source_id = maplibre_core::string::string_view(source_id);
414 let mut coordinates = [sys::mln_lat_lng {
415 latitude: 0.0,
416 longitude: 0.0,
417 }; 4];
418 let mut coordinate_count = 0;
419 let mut found = false;
420 maplibre_core::check(unsafe {
424 sys::mln_map_get_image_source_coordinates(
425 map,
426 source_id.raw(),
427 coordinates.as_mut_ptr(),
428 coordinates.len(),
429 &mut coordinate_count,
430 &mut found,
431 )
432 })?;
433 if !found {
434 return Ok(None);
435 }
436 if coordinate_count != coordinates.len() {
437 return Err(Error::new(
438 ErrorKind::NativeError,
439 None,
440 "native image source coordinate count did not match Rust image source invariant",
441 ));
442 }
443 Ok(Some(coordinates.map(LatLng::from_native)))
444 }
445
446 pub fn remove_style_source(&self, source_id: &str) -> Result<bool> {
451 let map = self.inner.as_ptr()?;
452 let source_id_key = source_id.to_owned();
453 let source_id = maplibre_core::string::string_view(source_id);
454 let mut removed = false;
455 maplibre_core::check(unsafe {
458 sys::mln_map_remove_style_source(map, source_id.raw(), &mut removed)
459 })?;
460 if removed {
461 self.inner
462 .custom_geometry_sources
463 .borrow_mut()
464 .remove(&source_id_key);
465 }
466 Ok(removed)
467 }
468
469 pub fn style_source_exists(&self, source_id: &str) -> Result<bool> {
471 let map = self.inner.as_ptr()?;
472 let source_id = maplibre_core::string::string_view(source_id);
473 let mut exists = false;
474 maplibre_core::check(unsafe {
477 sys::mln_map_style_source_exists(map, source_id.raw(), &mut exists)
478 })?;
479 Ok(exists)
480 }
481
482 pub fn set_style_image(
484 &self,
485 image_id: &str,
486 image: &PremultipliedRgba8Image,
487 options: Option<&StyleImageOptions>,
488 ) -> Result<()> {
489 let map = self.inner.as_ptr()?;
490 let image_id = maplibre_core::string::string_view(image_id);
491 let image = maplibre_core::values::premultiplied_rgba8_image_to_native(image);
492 let options = options.map(StyleImageOptions::to_native);
493 let options_ptr = options.as_ref().map_or(ptr::null(), ptr::from_ref);
494 maplibre_core::check(unsafe {
498 sys::mln_map_set_style_image(map, image_id.raw(), &image, options_ptr)
499 })
500 }
501
502 pub fn remove_style_image(&self, image_id: &str) -> Result<bool> {
506 let map = self.inner.as_ptr()?;
507 let image_id = maplibre_core::string::string_view(image_id);
508 let mut removed = false;
509 maplibre_core::check(unsafe {
512 sys::mln_map_remove_style_image(map, image_id.raw(), &mut removed)
513 })?;
514 Ok(removed)
515 }
516
517 pub fn style_image_exists(&self, image_id: &str) -> Result<bool> {
519 let map = self.inner.as_ptr()?;
520 let image_id = maplibre_core::string::string_view(image_id);
521 let mut exists = false;
522 maplibre_core::check(unsafe {
525 sys::mln_map_style_image_exists(map, image_id.raw(), &mut exists)
526 })?;
527 Ok(exists)
528 }
529
530 pub fn style_image_info(&self, image_id: &str) -> Result<Option<StyleImageInfo>> {
532 let map = self.inner.as_ptr()?;
533 let image_id = maplibre_core::string::string_view(image_id);
534 let mut info = maplibre_core::style::empty_style_image_info();
535 let mut found = false;
536 maplibre_core::check(unsafe {
540 sys::mln_map_get_style_image_info(map, image_id.raw(), &mut info, &mut found)
541 })?;
542 Ok(found.then(|| maplibre_core::values::style_image_info_from_native(&info)))
543 }
544
545 pub fn copy_style_image_premultiplied_rgba8(
547 &self,
548 image_id: &str,
549 ) -> Result<Option<StyleImage>> {
550 let map = self.inner.as_ptr()?;
551 let image_id = maplibre_core::string::string_view(image_id);
552 let mut raw_info = maplibre_core::style::empty_style_image_info();
553 let mut info_found = false;
554 maplibre_core::check(unsafe {
558 sys::mln_map_get_style_image_info(map, image_id.raw(), &mut raw_info, &mut info_found)
559 })?;
560 if !info_found {
561 return Ok(None);
562 }
563 let info = maplibre_core::values::style_image_info_from_native(&raw_info);
564
565 let mut data = vec![0u8; info.byte_length];
566 let mut copied_size = 0;
567 let mut found = false;
568 let pixels = if data.is_empty() {
569 ptr::null_mut()
570 } else {
571 data.as_mut_ptr()
572 };
573 maplibre_core::check(unsafe {
577 sys::mln_map_copy_style_image_premultiplied_rgba8(
578 map,
579 image_id.raw(),
580 pixels,
581 data.len(),
582 &mut copied_size,
583 &mut found,
584 )
585 })?;
586 if !found {
587 return Ok(None);
588 }
589 maplibre_core::style::style_image_from_copied_premultiplied_rgba8(info, data, copied_size)
590 .map(Some)
591 }
592
593 pub fn style_source_type(&self, source_id: &str) -> Result<Option<SourceType>> {
595 let map = self.inner.as_ptr()?;
596 let source_id = maplibre_core::string::string_view(source_id);
597 let mut raw_source_type = sys::MLN_STYLE_SOURCE_TYPE_UNKNOWN;
598 let mut found = false;
599 maplibre_core::check(unsafe {
602 sys::mln_map_get_style_source_type(
603 map,
604 source_id.raw(),
605 &mut raw_source_type,
606 &mut found,
607 )
608 })?;
609 Ok(found.then(|| SourceType::from_raw(raw_source_type)))
610 }
611
612 pub fn style_source_info(&self, source_id: &str) -> Result<Option<SourceInfo>> {
614 let map = self.inner.as_ptr()?;
615 let source_id = maplibre_core::string::string_view(source_id);
616 let mut info = maplibre_core::style::empty_style_source_info();
617 let mut found = false;
618 maplibre_core::check(unsafe {
622 sys::mln_map_get_style_source_info(map, source_id.raw(), &mut info, &mut found)
623 })?;
624 if !found {
625 return Ok(None);
626 }
627
628 let attribution = if info.has_attribution {
629 match self.copy_style_source_attribution(map, source_id.raw(), info.attribution_size)? {
630 Some(attribution) => Some(attribution),
631 None => return Ok(None),
632 }
633 } else {
634 None
635 };
636
637 Ok(Some(maplibre_core::style::style_source_info_from_native(
638 &info,
639 attribution,
640 )))
641 }
642
643 fn copy_style_source_attribution(
644 &self,
645 map: *mut sys::mln_map,
646 source_id: sys::mln_string_view,
647 attribution_size: usize,
648 ) -> Result<Option<String>> {
649 if attribution_size == 0 {
650 let mut copied_size = 0;
651 let mut found = false;
652 maplibre_core::check(unsafe {
656 sys::mln_map_copy_style_source_attribution(
657 map,
658 source_id,
659 ptr::null_mut(),
660 0,
661 &mut copied_size,
662 &mut found,
663 )
664 })?;
665 return Ok(found.then(String::new));
666 }
667
668 let mut buffer = vec![0u8; attribution_size];
669 let mut copied_size = 0;
670 let mut found = false;
671 maplibre_core::check(unsafe {
675 sys::mln_map_copy_style_source_attribution(
676 map,
677 source_id,
678 buffer.as_mut_ptr().cast(),
679 buffer.len(),
680 &mut copied_size,
681 &mut found,
682 )
683 })?;
684 if !found {
685 return Ok(None);
686 }
687 if copied_size > buffer.len() {
688 return Err(Error::new(
689 ErrorKind::NativeError,
690 None,
691 "native style source attribution size exceeded caller buffer",
692 ));
693 }
694 buffer.truncate(copied_size);
695 String::from_utf8(buffer).map(Some).map_err(|error| {
696 Error::invalid_argument(format!(
697 "native style source attribution was not valid UTF-8: {error}"
698 ))
699 })
700 }
701
702 pub fn add_geojson_source_data(&self, source_id: &str, data: &GeoJson) -> Result<()> {
704 let map = self.inner.as_ptr()?;
705 let source_id = maplibre_core::string::string_view(source_id);
706 let data = data.try_to_native()?;
707 maplibre_core::check(unsafe {
710 sys::mln_map_add_geojson_source_data(map, source_id.raw(), data.as_ptr())
711 })
712 }
713
714 pub fn set_geojson_source_data(&self, source_id: &str, data: &GeoJson) -> Result<()> {
716 let map = self.inner.as_ptr()?;
717 let source_id = maplibre_core::string::string_view(source_id);
718 let data = data.try_to_native()?;
719 maplibre_core::check(unsafe {
722 sys::mln_map_set_geojson_source_data(map, source_id.raw(), data.as_ptr())
723 })
724 }
725
726 pub fn add_style_layer_json(
728 &self,
729 layer_json: &JsonValue,
730 before_layer_id: Option<&str>,
731 ) -> Result<()> {
732 let map = self.inner.as_ptr()?;
733 let layer_json = layer_json.try_to_native()?;
734 let before_layer_id = maplibre_core::string::string_view(before_layer_id.unwrap_or(""));
735 maplibre_core::check(unsafe {
738 sys::mln_map_add_style_layer_json(map, layer_json.as_ptr(), before_layer_id.raw())
739 })
740 }
741
742 pub fn add_hillshade_layer(
744 &self,
745 layer_id: &str,
746 source_id: &str,
747 before_layer_id: Option<&str>,
748 ) -> Result<()> {
749 let map = self.inner.as_ptr()?;
750 let layer_id = maplibre_core::string::string_view(layer_id);
751 let source_id = maplibre_core::string::string_view(source_id);
752 let before_layer_id = maplibre_core::string::string_view(before_layer_id.unwrap_or(""));
753 maplibre_core::check(unsafe {
755 sys::mln_map_add_hillshade_layer(
756 map,
757 layer_id.raw(),
758 source_id.raw(),
759 before_layer_id.raw(),
760 )
761 })
762 }
763
764 pub fn add_color_relief_layer(
766 &self,
767 layer_id: &str,
768 source_id: &str,
769 before_layer_id: Option<&str>,
770 ) -> Result<()> {
771 let map = self.inner.as_ptr()?;
772 let layer_id = maplibre_core::string::string_view(layer_id);
773 let source_id = maplibre_core::string::string_view(source_id);
774 let before_layer_id = maplibre_core::string::string_view(before_layer_id.unwrap_or(""));
775 maplibre_core::check(unsafe {
777 sys::mln_map_add_color_relief_layer(
778 map,
779 layer_id.raw(),
780 source_id.raw(),
781 before_layer_id.raw(),
782 )
783 })
784 }
785
786 pub fn add_location_indicator_layer(
788 &self,
789 layer_id: &str,
790 before_layer_id: Option<&str>,
791 ) -> Result<()> {
792 let map = self.inner.as_ptr()?;
793 let layer_id = maplibre_core::string::string_view(layer_id);
794 let before_layer_id = maplibre_core::string::string_view(before_layer_id.unwrap_or(""));
795 maplibre_core::check(unsafe {
797 sys::mln_map_add_location_indicator_layer(map, layer_id.raw(), before_layer_id.raw())
798 })
799 }
800
801 pub fn set_location_indicator_location(
803 &self,
804 layer_id: &str,
805 coordinate: LatLng,
806 altitude: f64,
807 ) -> Result<()> {
808 let map = self.inner.as_ptr()?;
809 let layer_id = maplibre_core::string::string_view(layer_id);
810 maplibre_core::check(unsafe {
813 sys::mln_map_set_location_indicator_location(
814 map,
815 layer_id.raw(),
816 coordinate.to_native(),
817 altitude,
818 )
819 })
820 }
821
822 pub fn set_location_indicator_bearing(&self, layer_id: &str, bearing: f64) -> Result<()> {
824 let map = self.inner.as_ptr()?;
825 let layer_id = maplibre_core::string::string_view(layer_id);
826 maplibre_core::check(unsafe {
828 sys::mln_map_set_location_indicator_bearing(map, layer_id.raw(), bearing)
829 })
830 }
831
832 pub fn set_location_indicator_accuracy_radius(
834 &self,
835 layer_id: &str,
836 radius: f64,
837 ) -> Result<()> {
838 let map = self.inner.as_ptr()?;
839 let layer_id = maplibre_core::string::string_view(layer_id);
840 maplibre_core::check(unsafe {
842 sys::mln_map_set_location_indicator_accuracy_radius(map, layer_id.raw(), radius)
843 })
844 }
845
846 pub fn set_location_indicator_image_name(
848 &self,
849 layer_id: &str,
850 image_kind: LocationIndicatorImageKind,
851 image_id: &str,
852 ) -> Result<()> {
853 let map = self.inner.as_ptr()?;
854 let layer_id = maplibre_core::string::string_view(layer_id);
855 let image_id = maplibre_core::string::string_view(image_id);
856 maplibre_core::check(unsafe {
859 sys::mln_map_set_location_indicator_image_name(
860 map,
861 layer_id.raw(),
862 image_kind.raw_value(),
863 image_id.raw(),
864 )
865 })
866 }
867
868 pub fn style_layer_json(&self, layer_id: &str) -> Result<Option<JsonValue>> {
870 let map = self.inner.as_ptr()?;
871 let layer_id = maplibre_core::string::string_view(layer_id);
872 let mut out = maplibre_core::ptr::OutPtr::<sys::mln_json_snapshot>::new();
873 let mut found = false;
874 maplibre_core::check(unsafe {
877 sys::mln_map_get_style_layer_json(map, layer_id.raw(), out.as_mut_ptr(), &mut found)
878 })?;
879 let snapshot = unsafe { maplibre_core::json::copy_json_snapshot(out.into_option()) }?;
882 if found { Ok(snapshot) } else { Ok(None) }
883 }
884
885 pub fn set_style_light_json(&self, light_json: &JsonValue) -> Result<()> {
887 let map = self.inner.as_ptr()?;
888 let light_json = light_json.try_to_native()?;
889 maplibre_core::check(unsafe { sys::mln_map_set_style_light_json(map, light_json.as_ptr()) })
891 }
892
893 pub fn set_style_light_property(&self, property_name: &str, value: &JsonValue) -> Result<()> {
895 let map = self.inner.as_ptr()?;
896 let property_name = maplibre_core::string::string_view(property_name);
897 let value = value.try_to_native()?;
898 maplibre_core::check(unsafe {
901 sys::mln_map_set_style_light_property(map, property_name.raw(), value.as_ptr())
902 })
903 }
904
905 pub fn style_light_property(&self, property_name: &str) -> Result<Option<JsonValue>> {
907 let map = self.inner.as_ptr()?;
908 let property_name = maplibre_core::string::string_view(property_name);
909 let mut out = maplibre_core::ptr::OutPtr::<sys::mln_json_snapshot>::new();
910 maplibre_core::check(unsafe {
913 sys::mln_map_get_style_light_property(map, property_name.raw(), out.as_mut_ptr())
914 })?;
915 unsafe { maplibre_core::json::copy_json_snapshot(out.into_option()) }
918 }
919
920 pub fn set_layer_property(
922 &self,
923 layer_id: &str,
924 property_name: &str,
925 value: &JsonValue,
926 ) -> Result<()> {
927 let map = self.inner.as_ptr()?;
928 let layer_id = maplibre_core::string::string_view(layer_id);
929 let property_name = maplibre_core::string::string_view(property_name);
930 let value = value.try_to_native()?;
931 maplibre_core::check(unsafe {
934 sys::mln_map_set_layer_property(
935 map,
936 layer_id.raw(),
937 property_name.raw(),
938 value.as_ptr(),
939 )
940 })
941 }
942
943 pub fn layer_property(&self, layer_id: &str, property_name: &str) -> Result<Option<JsonValue>> {
945 let map = self.inner.as_ptr()?;
946 let layer_id = maplibre_core::string::string_view(layer_id);
947 let property_name = maplibre_core::string::string_view(property_name);
948 let mut out = maplibre_core::ptr::OutPtr::<sys::mln_json_snapshot>::new();
949 maplibre_core::check(unsafe {
952 sys::mln_map_get_layer_property(
953 map,
954 layer_id.raw(),
955 property_name.raw(),
956 out.as_mut_ptr(),
957 )
958 })?;
959 unsafe { maplibre_core::json::copy_json_snapshot(out.into_option()) }
962 }
963
964 pub fn set_layer_filter(&self, layer_id: &str, filter: Option<&JsonValue>) -> Result<()> {
966 let map = self.inner.as_ptr()?;
967 let layer_id = maplibre_core::string::string_view(layer_id);
968 let native_filter = filter.map(JsonValue::try_to_native).transpose()?;
969 maplibre_core::check(unsafe {
972 sys::mln_map_set_layer_filter(
973 map,
974 layer_id.raw(),
975 native_filter
976 .as_ref()
977 .map_or(ptr::null(), |filter| filter.as_ptr()),
978 )
979 })
980 }
981
982 pub fn layer_filter(&self, layer_id: &str) -> Result<Option<JsonValue>> {
984 let map = self.inner.as_ptr()?;
985 let layer_id = maplibre_core::string::string_view(layer_id);
986 let mut out = maplibre_core::ptr::OutPtr::<sys::mln_json_snapshot>::new();
987 maplibre_core::check(unsafe {
990 sys::mln_map_get_layer_filter(map, layer_id.raw(), out.as_mut_ptr())
991 })?;
992 unsafe { maplibre_core::json::copy_json_snapshot(out.into_option()) }
995 }
996
997 pub fn style_source_ids(&self) -> Result<Vec<String>> {
999 let map = self.inner.as_ptr()?;
1000 let mut out = maplibre_core::ptr::OutPtr::<sys::mln_style_id_list>::new();
1001 maplibre_core::check(unsafe { sys::mln_map_list_style_source_ids(map, out.as_mut_ptr()) })?;
1005 unsafe { maplibre_core::style::copy_style_id_list(out.into_non_null("mln_style_id_list")?) }
1008 }
1009
1010 pub fn style_layer_ids(&self) -> Result<Vec<String>> {
1012 let map = self.inner.as_ptr()?;
1013 let mut out = maplibre_core::ptr::OutPtr::<sys::mln_style_id_list>::new();
1014 maplibre_core::check(unsafe { sys::mln_map_list_style_layer_ids(map, out.as_mut_ptr()) })?;
1018 unsafe { maplibre_core::style::copy_style_id_list(out.into_non_null("mln_style_id_list")?) }
1021 }
1022}