将 InfoWindow 添加到 FastPointOverlay - OsmDroid

如何解决将 InfoWindow 添加到 FastPointOverlay - OsmDroid

最初我使用 Marker 类实现了所需的功能,但是当获得更多的点时性能会严重下降,所以我将 SimpleFastPointOverlay 与 PopUpwindow 结合使用。

public class OpenMapFragment extends Fragment {
    private Map<Integer,MyPoint> myPointsMap;
    private Context context;
    private Pageviewmodel pageviewmodel;
    private MapView map = null;
    private SimpleFastPointOverlay sfpo;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getParentFragment() != null) {
            pageviewmodel = new viewmodelProvider(getParentFragment()).get(Pageviewmodel.class);
        }
        context = requireActivity().getApplicationContext();

    }

    @Override
    public View onCreateView(
            @NonNull LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_open_map,container,false);
        LocationManager locationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE);
        Location location = locationManager.getLastKNownLocation(LocationManager.GPS_PROVIDER);
        map = root.findViewById(R.id.mapview);
        map.setTileSource(TileSourceFactory.MAPNIK);
        map.setMultiTouchControls(true);
        myPointsMap = new HashMap<>();
        pageviewmodel.getMyPoints().observe(getViewLifecycleOwner(),myPointsList -> {
           myPointsMap = 
               myPointsList.stream().collect(Collectors.toMap(MyPoint::getId,p -> p));
           if (sfpo != null) {
               map.getoverlays().remove(sfpo);
           }
           sfpo = simpleFastPointOverlayBuilder(myPointsList);
           sfpo.setonClickListener((points,point) -> {
                MyPoint mp = myPointsMap
                        .get(Integer.valueOf(((LabelledGeoPoint) points.get(point)).getLabel()));

                View popupView = inflater.inflate(R.layout.popup_window,null);
                TextView txtId = popupView.findViewById(R.id.txt_id);
                txtId.setText("id:" + mp.getId());

                int width = LinearLayout.LayoutParams.WRAP_CONTENT;
                int height = LinearLayout.LayoutParams.WRAP_CONTENT;
                final PopupWindow popupWindow = new PopupWindow(popupView,width,height,true);

                popupWindow.showAtLocation(getView(),Gravity.CENTER,0);

                popupView.setonTouchListener(new View.OnTouchListener() {
                    @Override
                    public boolean onTouch(View v,MotionEvent event) {
                        popupWindow.dismiss();
                        return true;
                    }
                });
            });
            map.getoverlays().add(sfpo);
        });
        return root;
    }

    private SimpleFastPointOverlay simpleFastPointOverlayBuilder(List<MyPoint> myPointList) {
        List<IGeoPoint> points = new ArrayList<>();

        Paint textStyle = new Paint();
        textStyle.setStyle(Paint.Style.FILL);
        textStyle.setColor(Color.parseColor("#111111"));
        textStyle.setTextAlign(Paint.Align.CENTER);
        textStyle.setTextSize(24);

        Paint pointStyle = new Paint();
        pointStyle.setStyle(Paint.Style.FILL);
        pointStyle.setColor(Color.rgb(255,0));

        for(MyPoint myPoint: myPointList) {
            points.add(new StyledLabelledGeoPoint(myPoint.getLocationInfo().latitude,myPoint.getLocationInfo().longitude,Integer.toString(myPoint.getId()),pointStyle,textStyle));
        }

        SimplePointTheme pointTheme = new SimplePointTheme(points);

        SimpleFastPointOverlayOptions opt = SimpleFastPointOverlayOptions.getDefaultStyle()
                .setSymbol(SimpleFastPointOverlayOptions.Shape.CIRCLE)
                .setAlgorithm(SimpleFastPointOverlayOptions.Renderingalgorithm.MAXIMUM_OPTIMIZATION)
                .seTradius(7).setIsClickable(true).setCellSize(12)
                .setMinZoomShowLabels(12);
        return new SimpleFastPointOverlay(pointTheme,opt);
    }


    @Override
    public void onResume() {
        super.onResume();
        map.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        map.onPause();
    }
}

虽然这是一种解决方法,但我不喜欢它,因为 popupView 位于显示的中心,并且无法与被点击元素的位置关联。有没有办法让 OsmDroid 的 Marker 和 InfoWindow 有类似的行为?

解决方法

我终于找到了解决办法: 为了获得所需的功能,我应该在每次点击 simpleFastPoint 时添加一个标记,如果另一个点击删除前一个并添加一个新的。所以性能仍然很好,但具有标记行为。我也让标记不可见

public class OpenMapFragment extends Fragment {
    private Map<Integer,MyPoint> myPointsMap;
    private Context context;
    private PageViewModel pageViewModel;
    private MapView map = null;
    private SimpleFastPointOverlay sfpo;
    private Marker marker;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getParentFragment() != null) {
            pageViewModel = new ViewModelProvider(getParentFragment()).get(PageViewModel.class);
        }
        context = requireActivity().getApplicationContext();

    }

    @Override
    public View onCreateView(
            @NonNull LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_open_map,container,false);
        LocationManager locationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE);
        Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        map = root.findViewById(R.id.mapview);
        map.setTileSource(TileSourceFactory.MAPNIK);
        map.setMultiTouchControls(true);
        myPointsMap = new HashMap<>();
        pageViewModel.getMyPoints().observe(getViewLifecycleOwner(),myPointsList -> {
           myPointsMap = 
               myPointsList.stream().collect(Collectors.toMap(MyPoint::getId,p -> p));
           if (sfpo != null) {
               map.getOverlays().remove(sfpo);
           }
           sfpo = simpleFastPointOverlayBuilder(myPointsList);
           sfpo.setOnClickListener((points,point) -> {
                MyPoint mp = myPointsMap
                        .get(Integer.valueOf(((LabelledGeoPoint) points.get(point)).getLabel()));
                if (marker != null) {
                    map.getOverlays().remove(marker);
                }
                marker = constructMarker(mp);
                map.getOverlays().add(marker);
            });
            map.getOverlays().add(sfpo);
        });
        return root;
    }

    private SimpleFastPointOverlay simpleFastPointOverlayBuilder(List<MyPoint> myPointList) {
        List<IGeoPoint> points = new ArrayList<>();

        Paint textStyle = new Paint();
        textStyle.setStyle(Paint.Style.FILL);
        textStyle.setColor(Color.parseColor("#111111"));
        textStyle.setTextAlign(Paint.Align.CENTER);
        textStyle.setTextSize(24);

        Paint pointStyle = new Paint();
        pointStyle.setStyle(Paint.Style.FILL);
        pointStyle.setColor(Color.rgb(255,0));

        for(MyPoint myPoint: myPointList) {
            points.add(new StyledLabelledGeoPoint(myPoint.getLocationInfo().latitude,myPoint.getLocationInfo().longitude,Integer.toString(myPoint.getId()),pointStyle,textStyle));
        }

        SimplePointTheme pointTheme = new SimplePointTheme(points);

        SimpleFastPointOverlayOptions opt = SimpleFastPointOverlayOptions.getDefaultStyle()
                .setSymbol(SimpleFastPointOverlayOptions.Shape.CIRCLE)
                .setAlgorithm(SimpleFastPointOverlayOptions.RenderingAlgorithm.MAXIMUM_OPTIMIZATION)
                .setRadius(7).setIsClickable(true).setCellSize(12)
                .setMinZoomShowLabels(12);
        return new SimpleFastPointOverlay(pointTheme,opt);
    }


    private Marker constructMarker(MyPoint l) {
        GeoPoint gp = new GeoPoint(l.getLocationInfo().latitude,l.getLocationInfo().longitude);
        Marker marker = new Marker(map);
        marker.setPosition(gp);
        CustomMarkerInfoWindow markerInfoWindow = new CustomMarkerInfoWindow(l,R.layout.marker_info_window,map);
        markerInfoWindow.open(marker,gp,0);
        marker.setAlpha((float) 0);
        marker.setInfoWindow(markerInfoWindow);
        marker.setInfoWindowAnchor(Marker.ANCHOR_CENTER,Marker.ANCHOR_BOTTOM);
        marker.setAnchor(Marker.ANCHOR_CENTER,Marker.ANCHOR_BOTTOM);
        return marker;
    }


    @Override
    public void onResume() {
        super.onResume();
        map.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        map.onPause();
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?