• 图文解说ChinaCock高德地图组件显示多个标注(四)


    前文介绍了如何在地图上通过设置标注来采集位置的经纬度,当用户采集了多个实体的位置信息后,我们就可以在地图上一次性显示这些实体的标注了!

    本文将介绍两方面内容:

    1.如何在地图上显示多个标注

    2.如何为标注显示详细信息标签。

    基于前文,接下来在地图上的做标注就很简单了,可以复用以前的代码,具体参阅:图文解说ChinaCock高德地图组件采集坐标 (二)

    接下来,我们再做一个过程:

    procedure TMarkerMapFrame.MarkerAll;
    var
      mk: TCCuniGUIAMap.TMarker;
    begin
      with UniMainModule do
      begin
        q.Close;
        q.Query.Text := '你的查询语句';
        q.Open;
    
        q.First;
        while not q.Eof do
        begin
          mk := AddMarker(q.FieldByName('FJD').AsFloat, q.FieldByName('FWD').AsFloat, q.FieldByName('FName').AsString);
    
          if (q.FieldByName('FJD').AsString <> '') and (q.FieldByName('FJD').AsString <> '') then
          begin
            mk:=  AddMarker(q.FieldByName('FJD').AsFloat, q.FieldByName('FWD').AsFloat, q.FieldByName('FName').AsString);
           mk.CustomParams.Values['name']:=q.FieldByName('FName').AsString;
          end;
          q.Next;
        end;
      end;
      // 适应地图对象 让所有对象都在地图最佳区域内
      self.CCuniGUIAMap1.SetFitView(True);
    
    end;

    该过程,通过查询一个TDataSet并循环这个数据集,在循环过程中调用AddMarker方法,在地图上画出每个实体的标注。

    画完所有的标注,调用地图的SetFitView方法,让所有的标注点正好都显示在地图上。

    同样,基于前文,可以实现当用户鼠标移动到一个标注时显示他的名称,但问题来了,如果用户想了解一个标注点时,如何支持呢?

    这里,我是这样实现的,就是当用户在一个标注点上单击鼠标,隐藏原来的名称标签,换成一个大的标签来显示详细信息。

    在实现的过程中,测试了两种方案,都可以满足上面的需求,接下来,分别介绍这两种方案的实现过程:

    一、Panel实现方式

    利用一个uniPanel组件,基于他设计详细的显示内容,注意这里的优点,就是可视化的设计这个Panel,发挥想象,你可以放置任意你想放置的可视控件进去。

    这里的技术难点在于如何确定uniPanel的显示位置,直接代码:

       self.CCuniGUIAMap1.LngLatToContainer(AMarker.Options.Position,
       procedure(AResult: CC.uniGUI.AMap.TPixel)
       begin
         var AText := self.CCuniGUIAMap1.Texts.Items[0];
         AText.Hide;
    
       // x为marker在地图中的x像素坐标 y为marker在地图容器中y的像素坐标
         DetailPanel.Top := Round(AResult.Y)- DetailPanel.Height - 40;
         DetailPanel.Left :=Round(AResult.X) -Round(DetailPanel.Width/2) + 10;
         DetailPanel.Visible := True;
       end);

    上面的算法,通过用户当前单击的AMarker对象,利用CCuniGUIAMap1.LngLatToContainer方法,计算出鼠标的坐标,然后再根据DetailPanel的宽、高计算出显示的位置,这里的算法是在标注的上方显示。

    二、Text实现方式

    基于地图控件的Text属性来显示详细内容,与前文的实现,利用标签Text对象显示标注的名称是一样的过程,只不过这里显示更多的内容。这种方式的优点是完全与地图集成一体,运行效率效率高。

    如果你会css则好实现,不会的话,就需要下面这段代码,在Form.OnCreate建立一个Text对象并用css定制他的显示格式,见代码:

      / 建立一个Text对象,显示标注的详细信息
      var
      AMarkerDetailText := self.CCuniGUIAMap1.Texts.Add;
      with AMarkerDetailText do
      begin
        with Options do
        begin
          // 指定鼠标悬停时的鼠标样式。
          Anchor := 'center';
          cursor := 'pointer';
          Options.Offset.Y := -105; // 1.49.19用这个
          if UniMainModule.CCuniGUIAMapKeys1.ApiVersion = '2.0' then
            Options.Offset.Y := -38; // 2.0用这个值
    
          Options.ExtData := 'Detail';
          // 设置文本样式,Object同css样式表,如:{'background-color':'red'}
          Style := '{'
          //
          // + '"padding":".75rem 1.25rem"'
          // + '"padding":"15px"'
            + '"padding":"15px 25px 15px 25px"'
          //
          // + ',"margin-bottom":"1rem"'
          //
            + ',"border-radius":".35rem"'
          //
            + ' ,"background-color":"rgba(30,159,255,0.8)"'
          // + ',"background-color": "blue"'
          // + ',"background-color": "#1E9FFF"'
    
          //
            + ',"border-width": 0'
          //
            + ',"box-shadow":"0 2px 6px 0 rgba(0, 0, 0, .5)"'
          //
            + ',"text-align":"left"'
          //
            + ',"font-size":"10px"'
          //
            + ',"color": "white"'
          //
            + ',"line-height": "20px"' + '}';
        end;
      end;

    建立好Text对象,在GUIAMap.OnMarkerClick事件中显示这个Text:

    procedure TMarkerMapFrame.CCuniGUIAMap1MarkerClick(
      const ASender: TObject;
      const AMarker: TCCuniGUIAMap.TMarker;
      const ALngLat: TLngLat;
      const AEventParams: TUniStrings);
    var
      s: string;
    begin
    
      //隐藏名称标签
      self.CCuniGUIAMap1.Texts.Items[0].Hide;
    
      s := AMarker.CustomParams.Values['MarkerName'] + '</br>' +
           AMarker.CustomParams.Values['zczj'] + '</br>' +
           AMarker.CustomParams.Values['zzc'] + '</br>' +
           AMarker.CustomParams.Values['gdzc'] + '</br>' +
           AMarker.CustomParams.Values['xssr'];
    
      var AMarkerDetailText := self.CCuniGUIAMap1.Texts.Items[1];
      AMarkerDetailText.Show;
      AMarkerDetailText.SetPosition(AMarker.Options.Position);
      AMarkerDetailText.SetText(s);
      //...
    end;

    这段代码也是使用Marker.CustomParams来传递的显示内容,当我们在建立Marker对象时,就确定好要显示的详细信息,原理同前文是一样的。

    当用户鼠标离开标注时,隐藏这个标签,代码如下,用的是OnMarkerMouseOut事件:

    procedure TMarkerMapFrame.CCuniGUIAMap1MarkerMouseOut(
    const ASender: TObject; 
    const AMarker: TCCuniGUIAMap.TMarker; 
    const ALngLat: TLngLat;
    const AEventParams: TUniStrings);
    begin
      // mouse离开标注时隐藏详细信息
      var AText := self.CCuniGUIAMap1.Texts.Items[1];
      AText.Hide;
    end;

    写到这里,本文计划分享的内容基本就完成了,相信结合以前的文章,你也能定制出完美的标签。

    需要补充的是,这种实现适用于少量的小于500个标注的情况情况,笔者测试,大于500的情况下会感觉到卡,对于海量标标的情况下,需要使用TLabelMarker来实现,接下来,我会继续分享,如何使用LabelMarker实现。

  • 相关阅读:
    NOIP2016 愤怒的小鸟
    LCIS code force 10D
    UVA 1398
    uva1382 Distant Galaxy
    洛谷-3930(我在洛谷上也写了题解)
    HDU-1505 City Game
    导弹拦截n logn的算法(单调性)洛谷1020
    POJ 1182 食物链
    POJ
    1202. 交换字符串中的元素
  • 原文地址:https://www.cnblogs.com/kinglandsoft/p/16267064.html
Copyright © 2020-2023  润新知