版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_28656671/article/details/85164402
Osmdroid覆盖物添加API功能介绍2----点线面覆盖物
前言
Osmdroid 和百度高德一样可以加载一些点线面图形到地图上面
当多个覆盖物在通一个点显示并被点击时,是根据覆盖物的点击事件是否返回true来判断是否消费该事件
1,点-ItemizedOverlay
这是一个可以显示多个点集合的覆盖物,它有两个实现类ItemizedIconOverlay,ItemizedOverlayWithFocus
- 方法
getDisplayedItems();
可以获取当前界面上显示的数据点 OverlayItem
可以通过setMarker
设置不同的显示图标
1.1 ItemizedIconOverlay
使用方式:
final ArrayList<OverlayItem> items = new ArrayList<>();
items.add(new OverlayItem("Hannover", "SampleDescription", new GeoPoint(52.370816, 9.735936)));
items.add(new OverlayItem("Berlin", "SampleDescription", new GeoPoint(52.518333, 13.408333)));
items.add(new OverlayItem("Washington", "SampleDescription", new GeoPoint(38.895000, -77.036667)));
/* OnTapListener for the Markers, shows a simple Toast. */
this.mMyLocationOverlay = new ItemizedIconOverlay<>(items,
new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
@Override
public boolean onItemSingleTapUp(final int index, final OverlayItem item) {
Toast.makeText(
SampleWithMinimapItemizedoverlay.this,
"Item '" + item.getTitle() + "' (index=" + index
+ ") got single tapped up", Toast.LENGTH_LONG).show();
return true; // We 'handled' this event.返回true就表示这个点击事件被消费掉了
}
@Override
public boolean onItemLongPress(final int index, final OverlayItem item) {
Toast.makeText(
SampleWithMinimapItemizedoverlay.this,
"Item '" + item.getTitle() + "' (index=" + index
+ ") got long pressed", Toast.LENGTH_LONG).show();
return false;//false表示这个事件可以继续向下传递
}
}, getApplicationContext());
this.mMapView.getOverlays().add(this.mMyLocationOverlay);
实现效果
1.1 ItemizedOverlayWithFocus
和ItemizedIconOverlay
不同的是这个覆盖物可以设置是否获取焦点,并且在获取焦点的时候显示一个文本框。并且可以自定义这个文本框的样式
使用代码:
/* Create a static ItemizedOverlay showing some Markers on various cities. */
final ArrayList<OverlayItem> items = new ArrayList<>();
items.add(new OverlayItem("Hannover", "Tiny SampleDescription", new GeoPoint(52.370816,
9.735936))); // Hannover
items.add(new OverlayItem("Berlin", "This is a relatively short SampleDescription.",
new GeoPoint(52.518333, 13.408333))); // Berlin
items.add(new OverlayItem(
"Washington",
"This SampleDescription is a pretty long one. Almost as long as a the great wall in china.",
new GeoPoint(38.895, -77.036667))); // Washington
items.add(new OverlayItem("San Francisco", "SampleDescription", new GeoPoint(37.7793,
-122.4192))); // San Francisco
/* OnTapListener for the Markers, shows a simple Toast. */
mMyLocationOverlay = new ItemizedOverlayWithFocus<>(items,
new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
@Override
public boolean onItemSingleTapUp(final int index, final OverlayItem item) {
Toast.makeText(
context,
"Item '" + item.getTitle() + "' (index=" + index
+ ") got single tapped up", Toast.LENGTH_LONG).show();
return true;
}
@Override
public boolean onItemLongPress(final int index, final OverlayItem item) {
Toast.makeText(
context,
"Item '" + item.getTitle() + "' (index=" + index
+ ") got long pressed", Toast.LENGTH_LONG).show();
return false;
}
}, context);
mMyLocationOverlay.setFocusItemsOnTap(true);
mMyLocationOverlay.setFocusedItem(0);
//https://github.com/osmdroid/osmdroid/issues/317
//you can override the drawing characteristics with this
mMyLocationOverlay.setMarkerBackgroundColor(Color.BLUE);
mMyLocationOverlay.setMarkerTitleForegroundColor(Color.WHITE);
mMyLocationOverlay.setMarkerDescriptionForegroundColor(Color.WHITE);
mMyLocationOverlay.setDescriptionBoxPadding(15);
mMapView.getOverlays().add(mMyLocationOverlay);
效果图:
2,Mark覆盖物
在地图上添加一个标记图片。
使用方式
GeoPoint startPoint = new GeoPoint(38.8977, -77.0365); //white house
points.add(startPoint);
Marker startMarker = new Marker(mMapView);
startMarker.setPosition(startPoint);
startMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
startMarker.setIcon(drawable);
startMarker.setTitle("White House");
startMarker.setSnippet("The White House is the official residence and principal workplace of the President of the United States.");
startMarker.setSubDescription("1600 Pennsylvania Ave NW, Washington, DC 20500");
startMarker.setOnMarkerClickListener(new Marker.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker, MapView mapView) {
marker.showInfoWindow();
return true;
}
});
mMapView.getOverlays().add(startMarker);
实现效果
3,线Polyline
实现方式
//mOsmPathOverlay = new OsmPathOverlay(context);
//mMapView.getOverlayManager().add(mOsmPathOverlay);
Polyline line = new Polyline(mMapView);
line.setTitle("Central Park, NYC");
line.setSubDescription(Polyline.class.getCanonicalName());
line.setWidth(20f);
List<GeoPoint> pts = new ArrayList<>();
//here, we create a polygon, note that you need 5 points in order to make a closed polygon (rectangle)
pts.add(new GeoPoint(40.796788, -73.949232));
pts.add(new GeoPoint(40.796788, -73.981762));
pts.add(new GeoPoint(40.768094, -73.981762));
pts.add(new GeoPoint(40.768094, -73.949232));
pts.add(new GeoPoint(40.796788, -73.949232));
line.setPoints(pts);
line.setGeodesic(true);
line.setInfoWindow(new BasicInfoWindow(R.layout.bonuspack_bubble, mMapView));
//Note, the info window will not show if you set the onclick listener
//line can also attach click listeners to the line
/*
line.setOnClickListener(new Polyline.OnClickListener() {
@Override
public boolean onClick(Polyline polyline, MapView mapView, GeoPoint eventPos) {
Toast.makeText(context, "Hello world!", Toast.LENGTH_LONG).show();
return false;
}
});*/
mMapView.getOverlayManager().add(line);
实现效果
4,面Polygon
使用方式
//here, we create a polygon using polygon class, note that you need 4 points in order to make a rectangle
Polygon polygon = new Polygon(mMapView);
polygon.setTitle("This is a polygon");
polygon.setSubDescription(Polygon.class.getCanonicalName());
polygon.setFillColor(Color.RED);
polygon.setVisible(true);
polygon.setStrokeColor(Color.BLACK);
polygon.setInfoWindow(new BasicInfoWindow(R.layout.bonuspack_bubble, mMapView));
pts = new ArrayList<>();
pts.add(new GeoPoint(40.886788, -73.959232));
pts.add(new GeoPoint(40.886788, -73.971762));
pts.add(new GeoPoint(40.878094, -73.971762));
pts.add(new GeoPoint(40.878094, -73.959232));
polygon.setPoints(pts);
mMapView.getOverlays().add(polygon);
实现效果
Polygon
可以构建复杂的面图形结构
setHoles(List<? extends List<GeoPoint>> holes)
效果:
5,路径演示功能
功能实现效果如下图所示
实现代码:
1,创建一个Polyline
对象
final Polyline line = new Polyline(mMapView);
line.setColor(COLOR_POLYLINE_STATIC);
line.setWidth(LINE_WIDTH_BIG);
line.setPoints(mGeoPoints);
line.getPaint().setStrokeCap(Paint.Cap.ROUND);
mMapView.getOverlayManager().add(line);
2,创建是ValueAnimator
执行动画效果
//路径切片
final MilestoneMeterDistanceSliceLister slicerForPath = new MilestoneMeterDistanceSliceLister();
//图片切片
final MilestoneMeterDistanceSliceLister slicerForIcon = new MilestoneMeterDistanceSliceLister();
final ValueAnimator percentageCompletion = ValueAnimator.ofFloat(0, 10000); // 10 kilometers
percentageCompletion.setDuration(5000); // 5 seconds
percentageCompletion.setStartDelay(1000); // 1 second
percentageCompletion.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//当前的位置
mAnimatedMetersSoFar = (float)animation.getAnimatedValue();
//路径
slicerForPath.setMeterDistanceSlice(0, mAnimatedMetersSoFar);
//图片当前的位置
slicerForIcon.setMeterDistanceSlice(mAnimatedMetersSoFar, mAnimatedMetersSoFar);
mMapView.invalidate();
}
});
percentageCompletion.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mAnimationEnded = true;
}
});
percentageCompletion.start();
3,创建绘制千米符号的MilestoneManager
final float backgroundRadius = 20;
final Paint backgroundPaint1 = getFillPaint(COLOR_BACKGROUND);
final Paint backgroundPaint2 = getFillPaint(COLOR_POLYLINE_ANIMATED);
final Paint textPaint1 = getTextPaint(COLOR_POLYLINE_STATIC);
final Paint textPaint2 = getTextPaint(COLOR_BACKGROUND);
final Paint borderPaint = getStrokePaint(COLOR_BACKGROUND, 2);
return new MilestoneManager(
//每一千米一个监听回调
new MilestoneMeterDistanceLister(1000),
new MilestoneDisplayer(0, false) {
@Override
protected void draw(final Canvas pCanvas, final Object pParameter) {
final double meters = (double)pParameter;
final int kilometers = (int)Math.round(meters / 1000);
//根据动画的执行过程绘制不同的符号
final boolean checked = meters < mAnimatedMetersSoFar || (kilometers == 10 && mAnimationEnded);
final Paint textPaint = checked ? textPaint2 : textPaint1;
final Paint backgroundPaint = checked ? backgroundPaint2 : backgroundPaint1;
final String text = "" + kilometers + "K";
final Rect rect = new Rect();
textPaint1.getTextBounds(text, 0, text.length(), rect);
pCanvas.drawCircle(0, 0, backgroundRadius, backgroundPaint);
pCanvas.drawText(text, -rect.left - rect.width() / 2, rect.height() / 2 - rect.bottom, textPaint);
pCanvas.drawCircle(0, 0, backgroundRadius + 1, borderPaint);
}
}
);
4,方向箭头
final Path arrowPath = new Path(); // a simple arrow towards the right
arrowPath.moveTo(-5, -5);
arrowPath.lineTo(5, 0);
arrowPath.lineTo(-5, 5);
arrowPath.close();
final Paint backgroundPaint = getFillPaint(COLOR_BACKGROUND);
return new MilestoneManager( // display an arrow at 500m every 1km
new MilestoneMeterDistanceLister(500),
new MilestonePathDisplayer(0, true, arrowPath, backgroundPaint) {
@Override
protected void draw(final Canvas pCanvas, final Object pParameter) {
final int halfKilometers = (int)Math.round(((double)pParameter / 500));
if (halfKilometers % 2 == 0) {
return;
}
super.draw(pCanvas, pParameter);
}
}
);
5,开始图标
/**
* Starting point
* @since 6.0.2
*/
private MilestoneManager getStartManager(final Bitmap pBitmap) {
return new MilestoneManager(
new MilestoneVertexLister(),
new MilestoneBitmapDisplayer(0, true,
pBitmap, pBitmap.getWidth() / 2, pBitmap.getHeight() / 2) {
@Override
protected void draw(final Canvas pCanvas, final Object pParameter) {
if (0 != (int)pParameter) { // we only draw the start
return;
}
super.draw(pCanvas, pParameter);
}
}
);
}
6,路径动画效果
final MilestoneMeterDistanceSliceLister slicerForPath = new MilestoneMeterDistanceSliceLister();
MilestoneManager pathManager = getAnimatedPathManager(slicerForPath)
/**
* Animated path
* @since 6.0.2
*/
private MilestoneManager getAnimatedPathManager(final MilestoneLister pMilestoneLister) {
final Paint slicePaint = getStrokePaint(COLOR_POLYLINE_ANIMATED, LINE_WIDTH_BIG);
return new MilestoneManager(pMilestoneLister, new MilestoneLineDisplayer(slicePaint));
}
7,图片动画效果
final Bitmap bitmap = BitmapFactory.decodeResource(getResources(), org.osmdroid.library.R.drawable.next);
final MilestoneMeterDistanceSliceLister slicerForIcon = new MilestoneMeterDistanceSliceLister();
MilestoneManager pathIconManager = getAnimatedIconManager(slicerForIcon, bitmap)
/**
* Animated icon
* @since 6.0.2
*/
private MilestoneManager getAnimatedIconManager(final MilestoneLister pMilestoneLister,
final Bitmap pBitmap) {
return new MilestoneManager(
pMilestoneLister,
new MilestoneBitmapDisplayer(0, true, pBitmap,
pBitmap.getWidth() / 2, pBitmap.getHeight() / 2)
);
}
8,添加到Polyline
中
final List<MilestoneManager> managers = new ArrayList<>();
managers.add(getAnimatedPathManager(slicerForPath));
managers.add(getAnimatedIconManager(slicerForIcon, bitmap));
managers.add(getHalfKilometerManager());
managers.add(getKilometerManager());
managers.add(getStartManager(bitmap));
line.setMilestoneManagers(managers);
9,整体代码
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import org.osmdroid.samplefragments.BaseSampleFragment;
import org.osmdroid.util.BoundingBox;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.overlay.milestones.MilestoneBitmapDisplayer;
import org.osmdroid.views.overlay.milestones.MilestoneDisplayer;
import org.osmdroid.views.overlay.milestones.MilestoneLister;
import org.osmdroid.views.overlay.milestones.MilestoneManager;
import org.osmdroid.views.overlay.milestones.MilestoneMeterDistanceLister;
import org.osmdroid.views.overlay.milestones.MilestoneMeterDistanceSliceLister;
import org.osmdroid.views.overlay.milestones.MilestonePathDisplayer;
import org.osmdroid.views.overlay.milestones.MilestoneLineDisplayer;
import org.osmdroid.views.overlay.milestones.MilestoneVertexLister;
import org.osmdroid.views.overlay.Polyline;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Fabrice on 28/12/2017.
* @since 6.0.0
*/
public class SampleRace extends BaseSampleFragment {
public static final String TITLE = "10K race in Paris";
private static final float LINE_WIDTH_BIG = 12;
private static final float TEXT_SIZE = 20;
private static final int COLOR_POLYLINE_STATIC = Color.BLUE;
private static final int COLOR_POLYLINE_ANIMATED = Color.GREEN;
private static final int COLOR_BACKGROUND = Color.WHITE;
private double mAnimatedMetersSoFar;
private boolean mAnimationEnded;
/**
* @since 6.0.3
*/
private final List<GeoPoint> mGeoPoints = getGeoPoints();
@Override
public String getSampleTitle() {
return TITLE;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
mMapView.post(new Runnable() {
@Override
public void run() {
final BoundingBox boundingBox = BoundingBox.fromGeoPoints(mGeoPoints);
mMapView.zoomToBoundingBox(boundingBox, false, 30);
}
});
super.onActivityCreated(savedInstanceState);
}
@Override
protected void addOverlays() {
super.addOverlays();
final Polyline line = new Polyline(mMapView);
line.setColor(COLOR_POLYLINE_STATIC);
line.setWidth(LINE_WIDTH_BIG);
line.setPoints(mGeoPoints);
line.getPaint().setStrokeCap(Paint.Cap.ROUND);
final List<MilestoneManager> managers = new ArrayList<>();
final MilestoneMeterDistanceSliceLister slicerForPath = new MilestoneMeterDistanceSliceLister();
final Bitmap bitmap = BitmapFactory.decodeResource(getResources(), org.osmdroid.library.R.drawable.next);
final MilestoneMeterDistanceSliceLister slicerForIcon = new MilestoneMeterDistanceSliceLister();
managers.add(getAnimatedPathManager(slicerForPath));
managers.add(getAnimatedIconManager(slicerForIcon, bitmap));
managers.add(getHalfKilometerManager());
managers.add(getKilometerManager());
managers.add(getStartManager(bitmap));
line.setMilestoneManagers(managers);
mMapView.getOverlayManager().add(line);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
final ValueAnimator percentageCompletion = ValueAnimator.ofFloat(0, 10000); // 10 kilometers
percentageCompletion.setDuration(5000); // 5 seconds
percentageCompletion.setStartDelay(1000); // 1 second
percentageCompletion.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mAnimatedMetersSoFar = (float)animation.getAnimatedValue();
slicerForPath.setMeterDistanceSlice(0, mAnimatedMetersSoFar);
slicerForIcon.setMeterDistanceSlice(mAnimatedMetersSoFar, mAnimatedMetersSoFar);
mMapView.invalidate();
}
});
percentageCompletion.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mAnimationEnded = true;
}
});
percentageCompletion.start();
}
}
/**
* @since 6.0.2
*/
private Paint getFillPaint(final int pColor) {
final Paint paint = new Paint();
paint.setColor(pColor);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
return paint;
}
/**
* @since 6.0.2
*/
private Paint getStrokePaint(final int pColor, final float pWidth) {
final Paint paint = new Paint();
paint.setStrokeWidth(pWidth);
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true);
paint.setColor(pColor);
paint.setStrokeCap(Paint.Cap.ROUND);
return paint;
}
/**
* @since 6.0.2
*/
private Paint getTextPaint(final int pColor) {
final Paint paint = new Paint();
paint.setColor(pColor);
paint.setTextSize(TEXT_SIZE);
paint.setAntiAlias(true);
return paint;
}
/**
* Kilometer milestones
* @since 6.0.2
*/
private MilestoneManager getKilometerManager() {
final float backgroundRadius = 20;
final Paint backgroundPaint1 = getFillPaint(COLOR_BACKGROUND);
final Paint backgroundPaint2 = getFillPaint(COLOR_POLYLINE_ANIMATED);
final Paint textPaint1 = getTextPaint(COLOR_POLYLINE_STATIC);
final Paint textPaint2 = getTextPaint(COLOR_BACKGROUND);
final Paint borderPaint = getStrokePaint(COLOR_BACKGROUND, 2);
return new MilestoneManager(
new MilestoneMeterDistanceLister(1000),
new MilestoneDisplayer(0, false) {
@Override
protected void draw(final Canvas pCanvas, final Object pParameter) {
final double meters = (double)pParameter;
final int kilometers = (int)Math.round(meters / 1000);
final boolean checked = meters < mAnimatedMetersSoFar || (kilometers == 10 && mAnimationEnded);
final Paint textPaint = checked ? textPaint2 : textPaint1;
final Paint backgroundPaint = checked ? backgroundPaint2 : backgroundPaint1;
final String text = "" + kilometers + "K";
final Rect rect = new Rect();
textPaint1.getTextBounds(text, 0, text.length(), rect);
pCanvas.drawCircle(0, 0, backgroundRadius, backgroundPaint);
pCanvas.drawText(text, -rect.left - rect.width() / 2, rect.height() / 2 - rect.bottom, textPaint);
pCanvas.drawCircle(0, 0, backgroundRadius + 1, borderPaint);
}
}
);
}
/**
* Half-kilometer milestones
* @since 6.0.2
*/
private MilestoneManager getHalfKilometerManager() {
final Path arrowPath = new Path(); // a simple arrow towards the right
arrowPath.moveTo(-5, -5);
arrowPath.lineTo(5, 0);
arrowPath.lineTo(-5, 5);
arrowPath.close();
final Paint backgroundPaint = getFillPaint(COLOR_BACKGROUND);
return new MilestoneManager( // display an arrow at 500m every 1km
new MilestoneMeterDistanceLister(500),
new MilestonePathDisplayer(0, true, arrowPath, backgroundPaint) {
@Override
protected void draw(final Canvas pCanvas, final Object pParameter) {
final int halfKilometers = (int)Math.round(((double)pParameter / 500));
if (halfKilometers % 2 == 0) {
return;
}
super.draw(pCanvas, pParameter);
}
}
);
}
/**
* Animated path
* @since 6.0.2
*/
private MilestoneManager getAnimatedPathManager(final MilestoneLister pMilestoneLister) {
final Paint slicePaint = getStrokePaint(COLOR_POLYLINE_ANIMATED, LINE_WIDTH_BIG);
return new MilestoneManager(pMilestoneLister, new MilestoneLineDisplayer(slicePaint));
}
/**
* Animated icon
* @since 6.0.2
*/
private MilestoneManager getAnimatedIconManager(final MilestoneLister pMilestoneLister,
final Bitmap pBitmap) {
return new MilestoneManager(
pMilestoneLister,
new MilestoneBitmapDisplayer(0, true, pBitmap,
pBitmap.getWidth() / 2, pBitmap.getHeight() / 2)
);
}
/**
* Starting point
* @since 6.0.2
*/
private MilestoneManager getStartManager(final Bitmap pBitmap) {
return new MilestoneManager(
new MilestoneVertexLister(),
new MilestoneBitmapDisplayer(0, true,
pBitmap, pBitmap.getWidth() / 2, pBitmap.getHeight() / 2) {
@Override
protected void draw(final Canvas pCanvas, final Object pParameter) {
if (0 != (int)pParameter) { // we only draw the start
return;
}
super.draw(pCanvas, pParameter);
}
}
);
}
/**
* @since 6.0.2
* TODO get a real list of geo points instead of this lousy manual list
*/
private List<GeoPoint> getGeoPoints() {
final List<GeoPoint> pts = new ArrayList<>();
pts.add(new GeoPoint(48.85546563875735,2.359844067173981)); // saint paul
pts.add(new GeoPoint(48.85737826660179,2.351524365470226)); // hôtel de ville
pts.add(new GeoPoint(48.86253652215784,2.3354870181106264)); // louvre 1
pts.add(new GeoPoint(48.86292409137066,2.3356209116511195)); // louvre 2
pts.add(new GeoPoint(48.86989982398147,2.332474413449688)); // opéra loop 1
pts.add(new GeoPoint(48.87019045840439,2.3327154218225985)); // opéra loop 2
pts.add(new GeoPoint(48.87100070303335,2.332420856033508)); // opéra loop 3
pts.add(new GeoPoint(48.871987070089496,2.3330367663197364)); // opéra loop 4
pts.add(new GeoPoint(48.87285012531207,2.3319923967039813)); // opéra loop 5
pts.add(new GeoPoint(48.87270041271832,2.33134970770962)); // opéra loop 6
pts.add(new GeoPoint(48.87166121883793,2.330720408069368)); // opéra loop 7
pts.add(new GeoPoint(48.87096547527885,2.331885281871564)); // opéra loop 8
pts.add(new GeoPoint(48.87003193074662,2.3321932370146783)); // opéra loop 9
pts.add(new GeoPoint(48.86989982398147,2.332474413449688)); // opéra loop 10
pts.add(new GeoPoint(48.864306984328245,2.3350719481351234)); // rue de l'échelle 1
pts.add(new GeoPoint(48.86316191644713,2.3338401275626666)); // rue de l'échelle 2
pts.add(new GeoPoint(48.866209500723855,2.3235169355912433)); // rivoli
pts.add(new GeoPoint(48.866729156977776,2.3223118937268623)); // concorde
pts.add(new GeoPoint(48.86901910330005,2.3239721736289027)); // madeleine loop 1
pts.add(new GeoPoint(48.8691952486765,2.3249897645366104)); // madeleine loop 2
pts.add(new GeoPoint(48.87022568670458,2.325927019319977)); // madeleine loop 3
pts.add(new GeoPoint(48.870489898165346,2.32583329384164)); // madeleine loop 4
pts.add(new GeoPoint(48.87073649426996,2.3250165432446863)); // madeleine loop 5
pts.add(new GeoPoint(48.87075410823092,2.3247085881016005)); // madeleine loop 6
pts.add(new GeoPoint(48.86957395913612,2.323570493007452)); // madeleine loop 7
pts.add(new GeoPoint(48.86901910330005,2.3239721736289027)); // madeleine loop 8
pts.add(new GeoPoint(48.86664988772853,2.3224457872673554)); // concorde 1
pts.add(new GeoPoint(48.866183077380335,2.3231420336778967)); // concorde 2
pts.add(new GeoPoint(48.865610568177935,2.3231688123859726)); // concorde 3
pts.add(new GeoPoint(48.86398108306007,2.321307692173235)); // concorde 4
pts.add(new GeoPoint(48.863531864319754,2.3216022579623257)); // concorde 5
pts.add(new GeoPoint(48.86047157217769,2.3306186871927252)); // pont césaire
pts.add(new GeoPoint(48.859105908108276,2.336824405441064)); // mitterrand 1
pts.add(new GeoPoint(48.858679130445125,2.3402407938844476)); // mitterrand 2
pts.add(new GeoPoint(48.85792514768071,2.342640914879439)); // pont neuf
pts.add(new GeoPoint(48.8563361600739,2.3489338967683864)); // pont notre dame
pts.add(new GeoPoint(48.85582206974299,2.3509713700276507)); // pont d'arcole
pts.add(new GeoPoint(48.85403498622509,2.3547049339593116)); // pont louis philippe
pts.add(new GeoPoint(48.85303073607055,2.3575358780393856)); // pont marie
pts.add(new GeoPoint(48.852894107137885,2.358500835434853)); // quai des célestins 1
pts.add(new GeoPoint(48.85275705072659,2.3589590819111095)); // quai des célestins 2
pts.add(new GeoPoint(48.852639573503986,2.3594411333991445)); // quai des célestins 3
pts.add(new GeoPoint(48.85244769344759,2.3598755748636506)); // quai des célestins 4
pts.add(new GeoPoint(48.85215399805951,2.360375480110463)); // quai des célestins 5
return pts;
}
}