Android Tutorial OSMDroid - MapView for B4A tutorial

Discussion in 'Tutorials & Examples' started by warwound, Mar 26, 2012.

  1. warwound

    warwound Expert Licensed User

    How about this...

    • OSMDroid_CircleOverlay
      Fields:
      • RADIUS_UNITS_TYPE_METERS As RadiusUnitsType
      • RADIUS_UNITS_TYPE_PIXELS As RadiusUnitsType
      Methods:
      • AddCircleOverlayItem (Center As GeoPoint, Radius As Float, RadiusUnitsType1 As RadiusUnitsType, StrokeWidth As Float, StrokeColor As Int) As CircleOverlayItem
        Creates, adds and return a CircleOverlayItem object.
      • AddCircleOverlayItem2 (Latitude As Double, Longitude As Double, Radius As Float, RadiusUnitsType1 As RadiusUnitsType, StrokeWidth As Float, StrokeColor As Int) As CircleOverlayItem
      • ClearCircleOverlayItems
        Clear the CircleOverlay of all CircleOverlayItems.
      • GetBoundingBox As BoundingBox
        Returns a BoundingBox that represents the area covered by the centers of all CircleOverlayItems.
      • Initialize
      • IsInitialized As Boolean
      • RemoveCircleOverlayItem (CircleOverlayItem1 As CircleOverlayItem) As Boolean
        Remove CircleOverlayItem1 from the CircleOverlay.
        Return True on success otherwise False.
    • OSMDroid_CircleOverlayItem
      Fields:
      • FILL As Style
        Geometry and text drawn with this style will be filled, ignoring all stroke-related settings in the paint.
      • FILL_AND_STROKE As Style
        Geometry and text drawn with this style will be both filled and stroked at the same time, respecting the stroke-related fields on the paint.
      • STROKE As Style
        Geometry and text drawn with this style will be stroked, respecting the stroke-related fields on the paint.
        This is the CircleOverlayItem default.
      Properties:
      • Center As GeoPoint
      • Radius As Float
      • RadiusUnitsType As RadiusUnitsType
      • StrokeColor As Int
      • StrokeStyle As Style
      • StrokeWidth As Float
      • Tag As Object
    The CircleOverlay displays CircleOverlayItems - a CircleOverlayItem has a center, radius, stroke width, stroke color, stroke type and Tag property.
    The CircleOverlay methods AddCircleOverlayItem and AddCircleOverlayItem2 create, add and return a CircleOverlayItem.
    That reference to the CircleOverlayItem can be used to remove it from the overlay using the method RemoveCircleOverlayItem.

    All CircleOverlayItem properties can be modified at runtime though you'll need to call the MapView Invalidate method to see any modifications applied.

    You can set a CircleOverlayItem radius in units of pixels (fixed size circle) or meters (circle size depends on zoom level).
    You can choose the stroke style (same as PathOverlay) of FILL, FILL_AND_STROKE or STROKE.
    And the CircleOverlay now has a GetBoundingBox method.

    Updated library files and demo b4a project can be downloaded from here: http://b4a.martinpearman.co.uk/osmdroid/CircleOverlay-20140505.zip.

    Martin.
     
  2. Spectre

    Spectre Active Member Licensed User

    fantastic. I try right away...
     
  3. Spectre

    Spectre Active Member Licensed User

    Hi Martin, great job...
    All works very well ... I have some problems on the distances in meters of the circle ...

    CircleOverlayItem1=CircleOverlay1.AddCircleOverlayItem(CurrentPosition, 300, CircleOverlay1.RADIUS_UNITS_TYPE_METERS, 2dip, Colors.red)

    300=200 meter +/-
    850=800 meter +/-
     
  4. warwound

    warwound Expert Licensed User

    @Spectre

    Look here: http://code.google.com/p/osmdroid/s...src/main/java/org/osmdroid/views/MapView.java.
    Lines around 1477:

    Code:
    public float metersToEquatorPixels(final float meters) {
                            
    return meters / (float) TileSystem.GroundResolution(0, mZoomLevelProjection);
                    
    }
    This is the method used to convert pixels to meters for each zoom level.
    So a circle with a radius of 300 meters will have the expected pixel size if it is centered on the equator.
    Further north or south will introduce inaccuracies due to the nature of a spherical projection.

    If you center your circles on the equator do you see a 'more correct' size?

    Martin.
     
  5. Spectre

    Spectre Active Member Licensed User

    I have read ... I try to make sure, thanks for the suggestion and the link.

    Riccardo.
     
  6. eronquillo

    eronquillo Member Licensed User

    Hi, is there an example on how to utilize gps coordinates from a MySQL DB to be used to display the markers within the bounding box?
     
  7. warwound

    warwound Expert Licensed User

    Can you give a bit more detail?

    Are you wanting to only select rows from your table that are within the map bounds and then create a marker for each row?

    Or are you wanting to select all rows from your table but only create a Marker if the row is within the map bounds?

    When the map bounds changes do you then need to query the database again?

    Martin.
     
  8. eronquillo

    eronquillo Member Licensed User

    Hi Martin! You're doing an awesome job with OSM Droid. I have incorporated your tutorials into a project where I can check in/out and then store the gps coordinates within an MySQL table. What I would like to do now is select the rows that have unique coordinates (lat and long) that reside within the bounding box and then display them. When the map moves, a re-query on the DB takes place and displays markers.


    Edward
     
  9. warwound

    warwound Expert Licensed User

    @eronquillo

    I don't think you'll find a specific example that'll do as you require.

    You say an MySQL database so presumably you're storing the coordinates online and not locally on the device?
    Take a look at this Google search https://www.google.co.uk/search?q=mysql+spatial+extensions&ie=UTF-8&oe=UTF-8.
    You'd make things easier to do if you use MySQL spatial extensions to store the coordinate data.
    It'll take a bit more time to set up table columns using a spatial data type instead of a float or double data type but once set up you'll be able to make much more efficient queries.

    Next, if each time the map is panned or zoomed you query your database for coordinates within the map bounds then you'll probably find you're making too many queries - if the user slowly pans the map bit by bit for example you don't want to query the database repeatedly.
    I'm not sure what best to suggest here, ideally you want to have the database locally on the device so you don't have to wait for network requests to complete.

    Have you seen the Spatialite library?
    Spatialite is basically SQLite with spatial extensions.
    A local (device based) spatialite database would enable you to make queries much faster and more efficiently than a remote MySQL database.

    I think what i'd try to do is:
    • Fetch all coordinates from the database in a single query.
    • Create a b4a Type with properties to contain the coordinate data, use a GeoPoint type for the coordinate property.
    • Iterate through the database query result creating a List of these b4a Type objects - an object for each row in the results.
    So you now have a List of objects, each object has a GeoPoint type property.
    When you want to update the Markers, get the map bounds as a BoundingBox and iterate through the List of objects:
    • If the object's GeoPoint is within the BoundingBox and the object hasn't yet been added to the map as a Marker then create and add a Marker to the map.
      If a Marker has already been created for the object and added to the map then do nothing.
    • If the object's GeoPoint is not within the BoundingBox and the object has a corresponding Marker on the map then remove the Marker.
      If the object has no corresponding Marker then do nothing.

    Martin.
     
  10. IslamQabel

    IslamQabel Active Member Licensed User

    Dear Warwound......
    I would like to save the current location in map view as image (take screen shot ), is there a way to do that???
    Thanks
     
  11. warwound

    warwound Expert Licensed User

    This has been asked before and there is still no option in OSMDroid to create a Bitmap from the MapView.
    There are various generic techniques to convert a View to a Bitmap but i'm not sure if these technqiues would work with the OSMDroid MapView.

    I can only suggest that you search the forum, here's a starting point: http://www.basic4ppc.com/android/forum/threads/get-bitmap-of-a-view.28236/

    Martin.
     
  12. Spectre

    Spectre Active Member Licensed User

    Hi Martin!
    to the problem of being able to always see the name of the point on the map next to the symbol, you can do something?

    Riccardo...
     
  13. warwound

    warwound Expert Licensed User

    Didn't you manage to use the new ViewHostOverlay and ViewHost objects to add Labels to the map next to each point?

    Martin.
     
    Spectre likes this.
  14. Spectre

    Spectre Active Member Licensed User

    Hi!
    you gave me an example, but the labels were visible only when you did click!, I was waiting for developments.
     
  15. warwound

    warwound Expert Licensed User

    I've attached a project that creates Markers and adds a Label for each Marker - the Labels are permanently visible.

    Martin.
     

    Attached Files:

  16. Spectre

    Spectre Active Member Licensed User

    now it works but I have labels that are not anchored to the icon and move the map ...
     
  17. warwound

    warwound Expert Licensed User

    On a zoom change as the map redraws, the Labels will be redrawn after the map, so there'll be a brief period where the Labels appear to not be anchored to the map.
    Is that what you're seeing?

    If you're not zooming the map then you should see the Labels anchored to the map and they should smoothly pan as you pan the map.

    Does my example in post #375 work as you require but the code you've added to your project not work as required?
     
  18. Spectre

    Spectre Active Member Licensed User

    It happens when I move the map ... See image when I move the icons moving to DX and SX labels ...
    In your example work ...
     

    Attached Files:

  19. warwound

    warwound Expert Licensed User

    Hmmm...
    That's odd.

    I would ask you to post your project so i can take a look but bet it's not something you want to post and also it's probably a big project too?
    How can i help you debug the problem?

    Can you post just the code that creates the ViewHost and ViewHostOverlay?

    Martin.
     
  20. Spectre

    Spectre Active Member Licensed User

    Hi Martin.

    I work on for quite some time, even though I was working in VB.net I would like to avoid if possible to publish for now. I have also tried to copy the code of your project, but the result is the same.
    Code:
    Sub load_WP ' load wp on map e fit to box+******************************************************************************************
    Dim i,kkk As Int
    Dim May_LatLng As LatLon
    Dim MarkersList As List

    MarkersList.Initialize
        
    Try

        
    If  Global.ListWPtoNavigate.Get(0) <> "" Then   
            May_LatLng.Initialize       
            
    Dim WPLoadOnMap As List
            WPLoadOnMap.Initialize
            spinWpSel.Clear
            
    For i=0 To Global.ListWPtoNavigate.Size -1       
                spinWpSel.Add(Global.ListWPtoNavigate.Get(i))
    'ad wp on spin to track   
                Dim Marker1 As OSMDroid_Marker
                ModWpAfterMArk(Global.ListWPtoNavigate.Get(i))           
                
    Dim g As Geodesic' conevert UTM To Lat lon
                g.Initialize
                
    Dim u As UTM
                  u.UtmXZone = CurrentWPFuse
                  u.X =CurrentWP_X
                  u.Y = CurrentWP_Y
              
    'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                If Global.Glob_FUSE_N=True Then
                    u.NorthHemisphere=
    True
                
    Else
                    u.NorthHemisphere=
    False
                
    End If
                
    'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                  Dim ll As LatLon
                  ll = g.WGS84UTMTOLatLon(u) 
                  May_LatLng.Lat=ll.Lat 
    'coordinate lat lon on active WP
                  May_LatLng.Lon=ll.Lon   
               
                Marker1.Initialize(NomeCurrentWPLong,CurrentWPZone &
    " " & CurrentWPFuse &" " & CurrentWP_X  &"-" & CurrentWP_Y ,May_LatLng.Lat, May_LatLng.Lon)
                
    Dim MarkerIcon As BitmapDrawable
               
                
    Dim AA1,AA2 As Int
                
    Dim DummyIcon As String
                
    Dim IconSrch As String
                   
                
    For kkk=0 To Global.ListIconWPMap.Size -1
                    IconSrch=Global.ListIconWPMap.Get(kkk)
                    AA1=IconSrch.IndexOf(
    "|")
                    IconSrch=IconSrch.SubString2(AA1+
    1,IconSrch.Length)           
                    
    If NomeCurrentWPLong.Contains(IconSrch) = True Then           
                        DummyIcon=Global.ListIconWPMap.Get(kkk)
                        DummyIcon=DummyIcon.SubString2(
    0,AA1)
                    
    End If
                
    Next       
               
                
    Try       
                    
    Dim Bitmap2 As Bitmap=LoadBitmap(Global.GPSDir & "/NatoIcon",DummyIcon)
                
    Catch
                    
    Dim Bitmap2 As Bitmap=LoadBitmap(Global.GPSDir & "/NatoIcon""Wp.png")       
                
    End Try
               
                MarkerIcon.Initialize(Bitmap2)
                Marker1.SetMarkerIcon(MarkerIcon)
                MarkersList.Add(Marker1)
               
                
    Dim MarkerLabel As Label
                MarkerLabel.Initialize(
    "")
                MarkerLabel.Color=
    Colors.Yellow
                MarkerLabel.TextColor=
    Colors.Black
                MarkerLabel.Gravity=
    Gravity.CENTER           
                MarkerLabel.TextSize=
    10
                MarkerLabel.Text=Marker1.GetTitle.ToUpperCase
               
                
    Dim ViewHost1 As OSMDroid_ViewHost
                ViewHost1.Initialize(MarkerLabel, Marker1.GetPoint, 
    00, Constants1.LayoutParams.ALIGN_CENTER, True)       
                ViewHostOverlay1.AddItem(ViewHost1)               
            
    Next       
           
            
    If LastMarker.IsInitialized = False Then
                LastMarker.Initialize(May_LatLng.Lat,May_LatLng.Lon)   
            
    Else
                LastMarker.Initialize(May_LatLng.Lat,May_LatLng.Lon)
            
    End If
           
            
    If MarkerOverlay1.IsInitialized Then
                MapView1.GetOverlays.Remove(MarkerOverlay1)
            
    End If
           
            MarkerOverlay1.Initialize2(
    "MarkerOverlay1", MapView1, Null)
            MarkerOverlay1.AddItems(MarkersList)
            MapView1.GetOverlays.Add(MarkerOverlay1)
           
        
    End If
    Catch
        
    Return
    End Try
    End Sub
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice