omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    Interactive visualization

    Pythonista
    4
    8
    2770
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • RichardSmith
      RichardSmith last edited by ccc

      Hello everyone, I am working with python quite a while now and am now faced with the task to program an interactive map visualization over time. I am working at an NGO which supports children in Uganda and we want to visualize all supported children and projects over time on a map of the area (animated). Furthermore some information about the projects (since when, how it helped) and children (age, supported since, etc.) should be shown when hovering or kicking the according dot on ths map. Which libraries and other things do you recommend for this project? Data is stored and edited as a CSV file including coordinates and other important information. Thank you for your help!

      cvp mikael 3 Replies Last reply Reply Quote 0
      • cvp
        cvp @RichardSmith last edited by

        @RichardSmith see an example here

        1 Reply Last reply Reply Quote 0
        • cvp
          cvp last edited by cvp

          Easier way to begin

          1 Reply Last reply Reply Quote 0
          • mikael
            mikael @RichardSmith last edited by

            @RichardSmith, I know this might sound odd in our forum, but if this is something you need to work on PCs and maybe send to others etc., I would suggest the map features of Excel.

            cvp 1 Reply Last reply Reply Quote 0
            • cvp
              cvp @mikael last edited by

              @mikael said:

              if this is something you need to work on PCs

              In this case, I agree but if he already knows Python and asks it for Pythonista...

              1 Reply Last reply Reply Quote 0
              • cvp
                cvp @RichardSmith last edited by cvp

                @RichardSmith Shortest script

                
                import console
                from objc_util import *
                import ctypes
                import ui
                
                class CLLocationCoordinate2D (Structure):
                	_fields_ = [('latitude', c_double), ('longitude', c_double)]
                class MKCoordinateSpan (Structure):
                	_fields_ = [('d_lat', c_double), ('d_lon', c_double)]
                class MKCoordinateRegion (Structure):
                	_fields_ = [('center', CLLocationCoordinate2D), ('span', MKCoordinateSpan)]
                	
                MKPointAnnotation = ObjCClass('MKPointAnnotation')
                MKPinAnnotationView = ObjCClass('MKPinAnnotationView')
                MKAnnotationView = ObjCClass('MKAnnotationView')
                UIColor = ObjCClass('UIColor') # used to set pin color
                		
                def mapView_viewForAnnotation_(self,cmd,mk_mapview,mk_annotation):
                	try:
                		# not specially called in the same sequence as pins created
                		# should have one MK(Pin)AnnotationView by type (ex: pin color)
                		annotation = ObjCInstance(mk_annotation)
                		mapView = ObjCInstance(mk_mapview)
                		if annotation.isKindOfClass_(MKPointAnnotation):
                			tit = str(annotation.title())
                			subtit = str(annotation.subtitle())
                			pin_color = annotation.pin_color
                			id = tit
                			pinView = mapView.dequeueReusableAnnotationViewWithIdentifier_(id)
                			
                			if not pinView:
                				pinView = MKPinAnnotationView.alloc().initWithAnnotation_reuseIdentifier_(annotation,id)
                				pinView.canShowCallout = True  	# tap-> show title
                				pinView.animatesDrop   = False   # not Animated pin falls like a drop
                				pinView.pinColor = pin_color # 0=red 1=green 2=purple
                			else:
                				pinView.annotation = annotation
                			return pinView.ptr
                		return None
                	except Exception as e:
                		print('Error on line {}'.format(sys.exc_info()[-1].tb_lineno), type(e).__name__, e)
                		
                # Build method of MKMapView Delegate
                methods = [mapView_viewForAnnotation_]
                protocols = ['MKMapViewDelegate']
                try:
                	MyMapViewDelegate = ObjCClass('MyMapViewDelegate')
                except Exception as e:
                	MyMapViewDelegate = create_objc_class('MyMapViewDelegate', methods=methods, protocols=protocols)	
                	#MyMapViewDelegate = create_objc_class('MyMapViewDelegate', NSObject, methods=methods, protocols=protocols)	
                class MapView(ui.View):
                
                	@on_main_thread
                	def __init__(self, *args, **kwargs):
                		ui.View.__init__(self, *args, **kwargs)
                		MKMapView = ObjCClass('MKMapView')
                		frame = CGRect(CGPoint(0, 0), CGSize(self.width, self.height))
                		self.mk_map_view = MKMapView.alloc().initWithFrame_(frame)
                		flex_width, flex_height = (1<<1), (1<<4)
                		self.mk_map_view.setAutoresizingMask_(flex_width|flex_height)
                		self_objc = ObjCInstance(self)
                		self_objc.addSubview_(self.mk_map_view)
                		self.mk_map_view.release()
                		
                		# Set Delegate of mk_map_view
                		map_delegate = MyMapViewDelegate.alloc().init()#.autorelease()
                		self.mk_map_view.setDelegate_(map_delegate)
                		
                	
                	@on_main_thread
                	def add_pin(self, lat, lon, color, title, subtitle):
                		global all_points
                		'''Add a pin annotation to the map'''
                		MKPointAnnotation = ObjCClass('MKPointAnnotation')
                		coord = CLLocationCoordinate2D(lat, lon)
                		all_points.append(coord)			# store all pin's for MKPolyline
                		annotation = MKPointAnnotation.alloc().init().autorelease()
                		annotation.setTitle_(title)
                		annotation.setSubtitle_(str(subtitle))
                		annotation.setCoordinate_(coord, restype=None, argtypes=[CLLocationCoordinate2D])
                		annotation.pin_color = color
                		self.mk_map_view.addAnnotation_(annotation)
                				
                		
                	@on_main_thread
                	def set_region(self, lat, lon, d_lat, d_lon, animated=False):
                		'''Set latitude/longitude of the view's center and the zoom level (specified implicitly as a latitude/longitude delta)'''
                		region = MKCoordinateRegion(CLLocationCoordinate2D(lat, lon), MKCoordinateSpan(d_lat, d_lon))
                		self.mk_map_view.setRegion_animated_(region, animated, restype=None, argtypes=[MKCoordinateRegion, c_bool])
                
                def main():
                	global all_points
                	
                	#----- Main process -----
                	console.clear()
                	
                	# Hide script
                	back = MapView()
                	back.background_color='white'
                	back.name = 'Test for @RichardSmith'
                	back.present('fullscreen', hide_title_bar=False)
                	
                	map_points = []
                	# assume infos come from a CSV file
                	map_points.append((0.5830414, 32.5316170, 0, 'Yoweri Museveni', '12 years, supported since 01/02/2019'))
                	map_points.append((0.2986261, 32.6033583, 1, "The Uganda National N.G.O Forum", 'since 1997, Providing a Sharing and Reflection Platform for NGOs in Uganda'))
                
                	# min and max of latitude and longitude
                	min_lat = min(map_points,key = lambda x:x[0])[0]
                	max_lat = max(map_points,key = lambda x:x[0])[0]
                	min_lon = min(map_points,key = lambda x:x[1])[1]
                	max_lon = max(map_points,key = lambda x:x[1])[1]
                	# Display map, center and zoom so all points are visible
                	back.set_region((min_lat+max_lat)/2,(min_lon+max_lon)/2, 4*(max_lat-min_lat), 4*(max_lon-min_lon), animated=True)
                	# Display pin's
                	all_points = []
                	for point in map_points:
                		back.add_pin(point[0],point[1],point[2],point[3],point[4])
                			
                # Protect against import	
                if __name__ == '__main__':
                	main()
                
                1 Reply Last reply Reply Quote 0
                • cvp
                  cvp last edited by

                  Add these lines if you want multiple lines in the subtitle

                  .
                  .
                  .
                  
                  				pinView.pinColor = pin_color # 0=red 1=green 2=purple
                  				# add these lines if you want several lines in subtitle: begin	
                  				l_title = ui.Label()
                  				l_title.font = ('Menlo',12)	# police echappement fixe
                  				lo = ObjCInstance(l_title)
                  				l_title.text = subtit.replace(',','\n')
                  				lo.setNumberOfLines_(0)
                  				pinView.setDetailCalloutAccessoryView_(lo)		
                  				# add these lines if you want several lines in subtitle: end
                  
                  

                  1 Reply Last reply Reply Quote 0
                  • jasper
                    jasper last edited by

                    This post is deleted!
                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post
                    Powered by NodeBB Forums | Contributors