다음을 통해 공유


지도에 관심 지점 표시

Important

엔터프라이즈용 Bing Maps 서비스 사용 중지

Windows.Services.Maps 네임스페이스의 UWP MapControl 및 지도 서비스는 Bing Maps를 사용합니다. 엔터프라이즈용 Bing Maps가 더 이상 사용되지 않아 사용 중지되며, 이 시점에서 MapControl 및 서비스는 데이터를 더 이상 수신하지 않습니다.

Bing Maps 설명서Bing Maps 개발자 센터를 참조하여 자세한 내용을 확인하세요.

참고 항목

MapControl 및 지도 서비스를 사용하려면 MapServiceToken이라는 지도 인증 키가 필요합니다. 맵 인증 키 가져오기 및 설정에 대한 자세한 내용은 맵 인증 키 요청을 참조하세요.

압정, 이미지, 도형 및 XAML UI 요소를 사용해서 지도에 POI(관심 지점)를 추가하세요. POI는 관심 있는 항목을 나타내는 지도상의 특정 지점입니다. 그 예가 바로 사업체, 도시 또는 친구의 위치입니다.

MapIcon, MapBillboard, MapPolygonMapPolyline 개체를 MapElementsLayer 개체의 MapElements 컬렉션에 추가하여 고정핀, 이미지 및 셰이프를 표시합니다. 그런 다음 해당 계층 개체를 지도 컨트롤의 계층 컬렉션에 추가합니다.

참고 항목

이전 릴리스의 가이드에서는 지도 요소를 MapElements 컬렉션에 추가하는 방법을 설명했습니다. 이 방법을 아직 사용할 수는 있지만 새 지도 계층 모델의 이점을 활용하지 못하게 됩니다. 자세한 내용은 이 가이드의 계층 작업 섹션을 참조하세요.

Button, HyperlinkButton 또는 TextBlock과 같은 XAML 사용자 인터페이스 요소를 MapItemsControl에 또는 MapControlChildren으로 추가하여 지도에서 이와 같은 XAML 사용자 인터페이스 요소를 표시할 수도 있습니다.

지도에 배치할 요소가 많은 경우에는 지도에 바둑판식 이미지 오버레이를 실행하는 것이 좋습니다. 지도에 도로를 표시하려면 경로 및 길 찾기를 표시합니다.

고정핀 추가

MapIcon 클래스를 사용해서 선택적 텍스트가 있는 이미지(예: 압정)를 지도에 표시하세요. Image(이미지) 속성을 사용하면 기본 이미지를 수락하거나 사용자 지정 이미지를 제공할 수 있습니다. 다음 이미지는 Title(제목) 속성에 대해 지정된 값이 없고 짧은 제목, 긴 제목, 매우 긴 제목이 있는 MapIcon의 기본 이미지를 표시합니다.

길이가 다른 제목이 있는 샘플 mapicon입니다.

다음 예제에서는 시애틀 시의 지도를 보여주고, Space Needle(스페이스 니들)의 위치가 표시되도록 기본 이미지와 선택적 제목을 사용하여 MapIcon을 추가합니다. 또한 지도를 아이콘 위로 가운데에 두고 확대합니다. 지도 컨트롤 사용 방법에 대한 전체 내용은 2D 뷰, 3D 뷰 및 거리 뷰가 있는 지도 표시하기를 참조하세요.

public void AddSpaceNeedleIcon()
{
    var MyLandmarks = new List<MapElement>();

    BasicGeoposition snPosition = new BasicGeoposition { Latitude = 47.620, Longitude = -122.349 };
    Geopoint snPoint = new Geopoint(snPosition);

    var spaceNeedleIcon = new MapIcon
    {
        Location = snPoint,
        NormalizedAnchorPoint = new Point(0.5, 1.0),
        ZIndex = 0,
        Title = "Space Needle"
    };

    MyLandmarks.Add(spaceNeedleIcon);

    var LandmarksLayer = new MapElementsLayer
    {
        ZIndex = 1,
        MapElements = MyLandmarks
    };

    myMap.Layers.Add(LandmarksLayer);

    myMap.Center = snPoint;
    myMap.ZoomLevel = 14;

}

이 예제에서는 지도(가운데의 기본 이미지)에 다음 POI를 표시합니다.

mapicon을 사용하여 지도

다음 코드 행에는 프로젝트의 Assets(자산) 폴더에 저장된 사용자 지정 이미지가 있는 MapIcon이 표시됩니다. MapIconImage(이미지) 속성에는 RandomAccessStreamReference 형식의 값이 필요합니다. 이 형식에는 Windows.Storage.Streams 네임스페이스에 대한 using 구문이 필요합니다.

참고 항목

여러 지도 아이콘에 같은 이미지를 사용할 경우 최상의 성능을 위해 페이지 또는 앱 수준에서 RandomAccessStreamReference를 선언합니다.

    MapIcon1.Image =
        RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/customicon.png"));

MapIcon 클래스를 사용할 때는 다음 사항을 염두에 두어야 합니다.

  • Image(이미지) 속성은 최대 이미지 크기를 2048×2048픽셀까지 지원합니다.
  • 지도 아이콘의 이미지는 기본적으로 표시되지 않습니다. 지도상의 다른 요소 또는 레이블을 가리면 이 이미지를 숨길 수 있습니다. 이미지를 계속 표시하려면 지도 아이콘의 CollisionBehaviorDesired 속성을 MapElementCollisionBehavior.RemainVisible로 설정하세요.
  • MapIcon의 선택적 제목은 표시되지 않습니다. 텍스트가 표시되지 않으면 MapControlZoomLevel 속성 값을 줄여서 축소하세요.
  • 지도의 특정 위치(예: 압정 또는 화살표)를 가리키는 MapIcon 이미지를 표시할 경우, NormalizedAnchorPoint 속성의 값을 이미지에 있는 포인터의 대략적인 위치로 설정하는 것이 좋습니다. NormalizedAnchorPoint 값을 이미지의 왼쪽 상단에 표시되는 기본값(0, 0)으로 두면 지도의 ZoomLevel이 변경되어 이미지가 다른 위치를 가리키게 될 수 있습니다.
  • AltitudeAltitudeReferenceSystem을 명시적으로 설정하지 않으면 표면에 MapIcon이 놓입니다.

3D 고정핀 추가

3D 개체를 지도에 추가할 수 있습니다. MapModel3D 클래스를 사용하여 3MF(3D 제조 형식) 파일에서 3D 개체를 가져옵니다.

이 이미지는 3D 커피잔을 사용하여 근처에 있는 커피숍의 위치를 표시합니다.

지도의 머그잔

다음 코드는 3MF 파일 가져오기를 사용하여 커피잔을 지도에 추가합니다. 간단히 작업하기 위해 이 코드는 이미지를 지도의 중심에 추가하지만 사용자 코드는 이미지를 특정 위치에 추가할 수 있습니다.

public async void Add3DMapModel()
{
    var mugStreamReference = RandomAccessStreamReference.CreateFromUri
        (new Uri("ms-appx:///Assets/mug.3mf"));

    var myModel = await MapModel3D.CreateFrom3MFAsync(mugStreamReference,
        MapModel3DShadingOption.Smooth);

    myMap.Layers.Add(new MapElementsLayer
    {
       ZIndex = 1,
       MapElements = new List<MapElement>
       {
          new MapElement3D
          {
              Location = myMap.Center,
              Model = myModel,
          },
       },
    });
}

이미지 추가

식당이나 랜드마크 사진 같은 지도 위치와 관련된 큰 이미지를 표시합니다. 사용자가 축소하면, 사용자가 지도의 더 많은 부분을 볼 수 있도록 이미지 크기가 비례해 축소됩니다. 이는 일반적으로 작고, 사용자가 지도를 축소 또는 확대했을 떄 동일한 크기를 유지하고, 특정 위치를 표시한 MapIcon과 다릅니다.

MapBillboard 이미지

다음은 위 이미지에 제시한 MapBillboard를 표시하는 코드입니다.

public void AddLandmarkPhoto()
{
    // Create MapBillboard.

    RandomAccessStreamReference mapBillboardStreamReference =
        RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/billboard.jpg"));

    var mapBillboard = new MapBillboard(myMap.ActualCamera)
    {
        Location = myMap.Center,
        NormalizedAnchorPoint = new Point(0.5, 1.0),
        Image = mapBillboardStreamReference
    };

    // Add MapBillboard to a layer on the map control.

    var MyLandmarkPhotos = new List<MapElement>();

    MyLandmarkPhotos.Add(mapBillboard);

    var LandmarksPhotoLayer = new MapElementsLayer
    {
        ZIndex = 1,
        MapElements = MyLandmarkPhotos
    };

    myMap.Layers.Add(LandmarksPhotoLayer);
}

코드에는 조금 더 자세히 검토할 3가지 부분이 있습니다. 이미지, 참조 카메라, NormalizedAnchorPoint 속성입니다.

이미지

프로젝트의 Assets 폴더에 저장된 사용자 지정 이미지를 표시하는 예제입니다. MapBillboardImage 속성은 RandomAccessStreamReference 유형의 값이 필요합니다. 이 형식에는 Windows.Storage.Streams 네임스페이스에 대한 using 구문이 필요합니다.

참고 항목

여러 지도 아이콘에 같은 이미지를 사용할 경우 최상의 성능을 위해 페이지 또는 앱 수준에서 RandomAccessStreamReference를 선언합니다.

참조 카메라

MapBillboard 이미지가 지도의 ZoomLevel 변경에 따라 크기가 축소 또는 확대되기 때문에, ZoomLevel에서 이미지가 일반적인 1x 크기로 표시되도록 정의하는 것이 중요합니다. 이 위치는 MapBillboard의 참조 카메라에서 정의되어 설정됩니다. MapCamera 개체를 MapBillboard 생성자로 보내야 합니다.

Geopoint에서 원하는 위치를 지정한 후, 이 Geopoint를 사용하여 MapCamera 개체를 만듭니다. 그러나 우리는 이 예제에서 지도 컨트롤의 ActualCamera가 반환한 MapCamera 개체만 사용합니다. 지도의 내부 카메라입니다. 해당 카메라의 현재 위치는 참조 카메라 위치입니다. MapBillboard 이미지가 1 x 크기로 표시되는 위치입니다.

앱이 사용자에게 지도를 확대할 수 있는 기능을 부여할 경우, 이미지 크기가 축소됩니다. 지도 내부 카메라의 고도가 상승하고, 1x 크기인 이미지가 참조 카메라 위치에 고정되기 때문입니다.

NormalizedAnchorPoint

NormalizedAnchorPointMapBillboard위치 속성에 고정된 이미지의 지점입니다. 지점 0.5,1이 이미지의 아래쪽 중앙입니다. MapBillboard위치 속성을 지도 컨트롤의 중앙으로 설정했기 때문에, 이미지 아래쪽 중앙이 지도 컨트롤 중앙에 고정됩니다. 이미지를 한 점 위에 바로 표시되게 하려면 NormalizedAnchorPoint를 0.5,0.5로 설정합니다.

도형 추가하기

MapPolygon 클래스를 사용해서 여러 개의 점으로 된 도형을 지도에 표시하세요. UWP 지도 샘플의 다음 예제는 테두리가 파란색인 빨간색 상자를 지도에 표시합니다.

public void HighlightArea()
{
    // Create MapPolygon.

    double centerLatitude = myMap.Center.Position.Latitude;
    double centerLongitude = myMap.Center.Position.Longitude;

    var mapPolygon = new MapPolygon
    {
        Path = new Geopath(new List<BasicGeoposition> {
                    new BasicGeoposition() {Latitude=centerLatitude+0.0005, Longitude=centerLongitude-0.001 },
                    new BasicGeoposition() {Latitude=centerLatitude-0.0005, Longitude=centerLongitude-0.001 },
                    new BasicGeoposition() {Latitude=centerLatitude-0.0005, Longitude=centerLongitude+0.001 },
                    new BasicGeoposition() {Latitude=centerLatitude+0.0005, Longitude=centerLongitude+0.001 },
                }),
        ZIndex = 1,
        FillColor = Colors.Red,
        StrokeColor = Colors.Blue,
        StrokeThickness = 3,
        StrokeDashed = false,
    };

    // Add MapPolygon to a layer on the map control.
    var MyHighlights = new List<MapElement>();

    MyHighlights.Add(mapPolygon);

    var HighlightsLayer = new MapElementsLayer
    {
        ZIndex = 1,
        MapElements = MyHighlights
    };

    myMap.Layers.Add(HighlightsLayer);
}

선 추가

MapPolyline 클래스를 사용해서 지도에 선을 표시하세요. UWP 지도 샘플의 다음 예제에서는 지도에 점선을 표시합니다.

public void DrawLineOnMap()
{
    // Create Polyline.

    double centerLatitude = myMap.Center.Position.Latitude;
    double centerLongitude = myMap.Center.Position.Longitude;
    var mapPolyline = new MapPolyline
    {
        Path = new Geopath(new List<BasicGeoposition> {
                    new BasicGeoposition() {Latitude=centerLatitude-0.0005, Longitude=centerLongitude-0.001 },
                    new BasicGeoposition() {Latitude=centerLatitude+0.0005, Longitude=centerLongitude+0.001 },
                }),
        StrokeColor = Colors.Black,
        StrokeThickness = 3,
        StrokeDashed = true,
    };

   // Add Polyline to a layer on the map control.

   var MyLines = new List<MapElement>();

   MyLines.Add(mapPolyline);

   var LinesLayer = new MapElementsLayer
   {
       ZIndex = 1,
       MapElements = MyLines
   };

   myMap.Layers.Add(LinesLayer);

}

XAML 추가

XAML을 사용해서 사용자 지정 UI 요소를 지도에 표시하세요. XAML의 위치 및 정규화된 앵커 지점을 지정해서 지도에 XAML을 배치하세요.

  • SetLocation을 호출해서 XAML이 배치되는 지도에서 위치를 설정하세요.
  • SetNormalizedAnchorPoint를 호출해서 지정된 위치에 해당하는 XAML에서 상대 위치를 설정하세요.

다음 예제에서는 시애틀 시의 지도를 보여주고, Space Needle(스페이스 니들)의 위치가 표시되도록 XAML Border(테두리) 컨트롤을 추가합니다. 또한 지도를 영역 위로 가운데에 두고 확대합니다. 지도 컨트롤 사용 방법에 대한 전체 내용은 2D 뷰, 3D 뷰 및 거리 뷰가 있는 지도 표시하기를 참조하세요.

private void displayXAMLButton_Click(object sender, RoutedEventArgs e)
{
   // Specify a known location.
   BasicGeoposition snPosition = new BasicGeoposition { Latitude = 47.620, Longitude = -122.349 };
   Geopoint snPoint = new Geopoint(snPosition);

   // Create a XAML border.
   Border border = new Border
   {
      Height = 100,
      Width = 100,
      BorderBrush = new SolidColorBrush(Windows.UI.Colors.Blue),
      BorderThickness = new Thickness(5),
   };

   // Center the map over the POI.
   MapControl1.Center = snPoint;
   MapControl1.ZoomLevel = 14;

   // Add XAML to the map.
   MapControl1.Children.Add(border);
   MapControl.SetLocation(border, snPoint);
   MapControl.SetNormalizedAnchorPoint(border, new Point(0.5, 0.5));
}

이 예제에서는 지도에 파란색 테두리를 표시합니다.

지도의 중간 지점에 표시된 xaml의 스크린샷

다음 예제에서는 데이터 바인딩을 이용해서 페이지의 XAML 태그에 XAML UI 요소를 직접 추가하는 방법을 보여줍니다. Children(하위 항목)은 콘텐츠를 표시하는 기타 XAML 요소와 마찬가지로 MapControl의 기본 콘텐츠 속성이며, XAML 태그에 명시적으로 지정할 필요가 없습니다.

이 예제에서는 두 개의 XAML 컨트롤을 MapControl의 암시적 하위 항목으로 표시하는 방법을 보여줍니다. 이러한 컨트롤은 지도에서 데이터가 바인딩된 위치에 표시됩니다.

<maps:MapControl>
    <TextBox Text="Seattle" maps:MapControl.Location="{x:Bind SeattleLocation}"/>
    <TextBox Text="Bellevue" maps:MapControl.Location="{x:Bind BellevueLocation}"/>
</maps:MapControl>

코드 숨김 파일의 속성을 사용하여 이러한 위치를 설정합니다.

public Geopoint SeattleLocation { get; set; }
public Geopoint BellevueLocation { get; set; }

이 예제에서는 MapItemsControl에 포함된 두 XAML 컨트롤을 표시하는 방법을 보여줍니다. 이러한 컨트롤은 지도에서 데이터가 바인딩된 위치에 표시됩니다.

<maps:MapControl>
  <maps:MapItemsControl>
    <TextBox Text="Seattle" maps:MapControl.Location="{x:Bind SeattleLocation}"/>
    <TextBox Text="Bellevue" maps:MapControl.Location="{x:Bind BellevueLocation}"/>
  </maps:MapItemsControl>
</maps:MapControl>

이 예제에서는 MapItemsControl에 바인딩된 XAML 요소의 컬렉션을 표시합니다.

<maps:MapControl x:Name="MapControl" MapTapped="MapTapped" MapDoubleTapped="MapTapped" MapHolding="MapTapped">
  <maps:MapItemsControl ItemsSource="{x:Bind LandmarkOverlays}">
      <maps:MapItemsControl.ItemTemplate>
          <DataTemplate>
              <StackPanel Background="Black" Tapped ="Overlay_Tapped">
                  <TextBlock maps:MapControl.Location="{Binding Location}" Text="{Binding Title}"
                    maps:MapControl.NormalizedAnchorPoint="0.5,0.5" FontSize="20" Margin="5"/>
              </StackPanel>
          </DataTemplate>
      </maps:MapItemsControl.ItemTemplate>
  </maps:MapItemsControl>
</maps:MapControl>

위의 예제에서 ItemsSource 속성은 코드 숨김 파일에서 IList 유형의 속성에 바인딩됩니다.

public sealed partial class Scenario1 : Page
{
    public IList LandmarkOverlays { get; set; }

    public MyClassConstructor()
    {
         SetLandMarkLocations();
         this.InitializeComponent();   
    }

    private void SetLandMarkLocations()
    {
        LandmarkOverlays = new List<MapElement>();

        var pikePlaceIcon = new MapIcon
        {
            Location = new Geopoint(new BasicGeoposition
            { Latitude = 47.610, Longitude = -122.342 }),
            Title = "Pike Place Market"
        };

        LandmarkOverlays.Add(pikePlaceIcon);

        var SeattleSpaceNeedleIcon = new MapIcon
        {
            Location = new Geopoint(new BasicGeoposition
            { Latitude = 47.6205, Longitude = -122.3493 }),
            Title = "Seattle Space Needle"
        };

        LandmarkOverlays.Add(SeattleSpaceNeedleIcon);
    }
}

계층 작업

이 가이드의 예제에서는 MapElementsLayer 컬렉션에 요소를 추가합니다. 그런 다음 해당 컬렉션을 지도 컨트롤의 계층 속성에 추가하는 방법을 보여줍니다. 이전 릴리스의 가이드에서는 다음과 같이 지도 요소를 MapElements 컬렉션에 추가하는 방법을 설명했습니다.

var pikePlaceIcon = new MapIcon
{
    Location = new Geopoint(new BasicGeoposition
    { Latitude = 47.610, Longitude = -122.342 }),
    NormalizedAnchorPoint = new Point(0.5, 1.0),
    ZIndex = 0,
    Title = "Pike Place Market"
};

myMap.MapElements.Add(pikePlaceIcon);

이 방법을 아직 사용할 수는 있지만 새 지도 계층 모델의 이점을 활용하지 못하게 됩니다. 요소를 계층으로 그룹화하면 각 계층을 서로 독립적으로 조작할 수 있습니다. 예를 들어 각 계층에 자신의 이벤트 세트가 있으므로 특정 계층에서 이벤트에 응답하고 해당 이벤트 관련 작업을 수행할 수 있습니다.

또한 XAML을 MapLayer에 직접 바인딩할 수 있습니다. 이 작업은 MapElements 컬렉션을 사용해서는 수행할 수 없습니다.

이 작업을 수행할 수 있는 한 가지 방법은 뷰 모델 클래스, 코드 숨김 XAML 페이지 및 XAML 페이지를 사용하는 것입니다.

뷰 모델 클래스

public class LandmarksViewModel
{
    public ObservableCollection<MapLayer> LandmarkLayer
        { get; } = new ObservableCollection<MapLayer>();

    public LandmarksViewModel()
    {
        var MyElements = new List<MapElement>();

        var pikePlaceIcon = new MapIcon
        {
            Location = new Geopoint(new BasicGeoposition
            { Latitude = 47.610, Longitude = -122.342 }),
            Title = "Pike Place Market"
        };

        MyElements.Add(pikePlaceIcon);

        var LandmarksLayer = new MapElementsLayer
        {
            ZIndex = 1,
            MapElements = MyElements
        };

        LandmarkLayer.Add(LandmarksLayer);         
    }

코드 숨김 XAML 페이지

뷰 모델 클래스를 코드 숨김 페이지에 연결합니다.

public LandmarksViewModel ViewModel { get; set; }

public myMapPage()
{
    this.InitializeComponent();
    this.ViewModel = new LandmarksViewModel();
}

XAML 페이지

XAML 페이지에서 계층을 반환하는 뷰 모델 클래스의 속성에 바인딩합니다.

<maps:MapControl
    x:Name="myMap" TransitFeaturesVisible="False" Loaded="MyMap_Loaded" Grid.Row="2"
    MapServiceToken="Your token" Layers="{x:Bind ViewModel.LandmarkLayer}"/>