TNTmips

HOME

FREE PRODUCTS
  TNTlite
  TNTatlas
  TNTsim3D

DOWNLOADS
  Release Version
  Development Version
  FTP
  Language Kits
  Sample Geodata
  Reseller Resources
  Promotional

DOCUMENTATION
  Tutorials
  Technical Guides
  Quick Guides

SITE MAP


label_management.sml

See other examples and scripts with DataTips and GraphTips ...


class GRE_GROUP g_group =MainLayout.GetGroupByName("Group 1");
class GRDEVICE_MEM_RGB24 imgdev;
class GRDEVICE_MEM_BINARY maskdev;
class GC imagegc, maskgc;
class GRE_GROUP group;

proc OnLayoutLoadEnd (
   class GRE_LAYOUT layout
   ) {
	group = layout.GetGroupByName("ProvinceMaps");
	g_group = group;
   }



func OnViewDataTipShowRequest (
	class GRE_VIEW view,
	class POINT2D point,		# Point in screen coordinates
	class TOOLTIP datatip
	) {
	datatip.Delay = 500;
	datatip.String = "";
	local class GRE_LAYER layer = g_group.FirstLayer;
	local class LABELPLACE place, places[];
	local class GRE_LABELS labels;
	local class POINT2D offset, delta, oldcenter, newpt, groupcenter, groupdelta, center;
	local class REGION2D reg, groupreg;
	local class RECT extents, groupextents, oldextents;
	local numeric zoom = 2.0, q, angle, SolutionFound, dTheta;
	local class POINT2D offsets[];
	local class LABELATTACHMENT attachment;
	local class POLYLINE leader;
	local class COLOR foregroundcolor;

	foregroundcolor.name = "red2";

	offset.x = 10;	# Offset so label doesn't fall under cursor
	offset.y = 10;
	imagegc = imgdev.CreateGC();

	while (layer) {
		labels = layer.GetLabels(view);
		labels.GetItemAtLocation(point, place, 10);

		reg = place.GetRegion();
		places = labels.GetItemsOverlappingRegion(reg);
		numeric number = places.GetNumItems();

		if (number > 1) {
			# Find the extents of the labels as they are on the screen
			groupreg.Clear();
			for q = 1 to number {
				groupreg.UnionRegion(places[q].GetRegion());
				}
			groupextents = groupreg.Extents;
			groupcenter = groupextents.center;
			# Expand the extents so that our labels will be placed far enough
			# out for their leader lines to look good
			groupextents.Expand(10, 10);

			# Compute zoomed extents so we know how big to make our window
			# and decide where we'll place the labels while we're at it
			reg.Clear();
			for q = 1 to number {
				place = places[q];
				center = place.GetRegion().Extents.center;
				angle = groupcenter.GetAngle(center);
				# Remove the leaders so we don't try to zoom them
				place.SetCopyOnWrite(1);
				while (place.GetNumAttachments()) {
				 	 place.DeleteAttachment(place.GetAttachment(1).Element);
					 }
			   zoom = 30 / place.GetRegion().Extents.GetHeight();
				if (zoom < 1.0) zoom = 1.0;
			  	place.Zoom(zoom);

				dTheta = 0;
				SolutionFound = false;
				while (!SolutionFound && dTheta < 360) {
					# Move out from center until label no longer intersects
					# the extents of the actual labels
					delta.x = cos(angle);
					delta.y = sin(angle);
					extents = place.GetRegion().Extents;
					offset.x = groupcenter.x - extents.center.x;
					offset.y = groupcenter.y - extents.center.y;
					extents += offset;

					while (groupextents.Overlaps(extents)) {
						offset += delta;
						extents += delta;
						}

					# Make sure this label won't overlap another one.  If it will,
					# move 10 degrees around and try again.  If we get all the
					# way around the circle and still can't find a spot, give up.
					SolutionFound = reg.TestRect(extents, "FullOutside");
					if (!SolutionFound) {
						dTheta += 10;
						angle += 10 / deg;
						}
					}

				offsets[q] = offset;
				place.Move(offset);
				reg.UnionRegion(place.GetRegion());
				}

			groupdelta.x = -reg.Extents.x1;
			groupdelta.y = -reg.Extents.y1;

			imgdev.Create(reg.Extents.GetHeight()+5,reg.Extents.GetWidth()+5);
			imgdev.SetPixelSizeMM(view.PixelSizeMillimeters, view.PixelSizeMillimeters);
			imgdev.Clear("white");
			imagegc = imgdev.CreateGC();
			imagegc.SetOutputScale(view.GetMapScale());

			maskdev.Create(imgdev.GetHeight(),imgdev.GetWidth());
			maskdev.SetPixelSizeMM(view.PixelSizeMillimeters, view.PixelSizeMillimeters);
			maskdev.ClearAll();
			maskgc = maskdev.CreateGC();
			maskgc.SetOutputScale(view.GetMapScale());
			maskgc.SetPixelFunction("Set");

			for q = 1 to number {
				place = places[q];
				oldextents = place.GetRegion().Extents;
				center = oldextents.center;
				oldextents += groupdelta;
				center += groupdelta;
				place.SetCopyOnWrite(1);
				# Remove the leaders so we don't try to zoom them
				while (place.GetNumAttachments()) {
				 	 place.DeleteAttachment(place.GetAttachment(1).Element);
					 }
			   zoom = 30 / place.GetRegion().Extents.GetHeight();
				if (zoom < 1.0) zoom = 1.0;
			  	place.Zoom(zoom);
				extents = place.GetRegion().Extents;
				delta = offsets[q] + groupdelta;
				extents += delta;
				newpt = extents.center;
				place.Move(delta);
				leader.Clear();
				leader.AppendVertex(center);
				leader.AppendVertex(newpt);
				attachment.Leader = leader;
				place.AddAttachment(attachment);

				# Draw the label to use as an image tip
				place.DrawSample(imagegc, foregroundcolor);
				# Draw again into a mask device
				place.DrawSample(maskgc, foregroundcolor);
				}


		 	# Figure out where to place the tip
		 	newpt.x = -groupdelta.x;
		 	newpt.y = -groupdelta.y;
		 	offset = newpt - point;

			# Show the tip
			datatip.SetImageTip(imgdev, maskdev, offset);
			return (1);
			}

		else {  # Single data tip case
			place = places[1];
			extents = place.GetRegion().Extents;
			oldcenter = extents.center;
			# Make sure we're modifying a COPY of the place, not the original
			place.SetCopyOnWrite(1);

			# Remove the leaders so we don't try to zoom them
			while (place.GetNumAttachments()) {
				place.DeleteAttachment(place.GetAttachment(1).Element);
				}

			zoom = 30 / place.GetRegion().Extents.GetHeight();# THIS IS CATCHING THE LABEL SIZE, IF IT IS SMALLER THAN 1, DON'T DO BELOW...
			# Zoom it up.  Maybe compute a zoom factor based on current size?

			if (zoom > 1.2) {
				place.Zoom(zoom);

				# Get new extents
				extents = place.GetRegion().Extents;

				# Move the label to (0,0)
				delta.x = -extents.x1;
				delta.y = -extents.y1;
				place.Move(delta);

				# Draw the label to use as an image tip
				imgdev.Create(extents.GetHeight()+2, extents.GetWidth()+2);
				imgdev.SetPixelSizeMM(view.PixelSizeMillimeters, view.PixelSizeMillimeters);
				imgdev.Clear("white");
				imagegc = imgdev.CreateGC();
				imagegc.SetOutputScale(view.GetMapScale());
				place.DrawSample(imagegc,foregroundcolor);

				# Draw again into a mask device
				maskdev.Create(imgdev.GetHeight(),imgdev.GetWidth());
				maskdev.SetPixelSizeMM(view.PixelSizeMillimeters, view.PixelSizeMillimeters);
				maskdev.ClearAll();
				maskgc = maskdev.CreateGC();
				maskgc.SetOutputScale(view.GetMapScale());
				maskgc.SetPixelFunction("Set");
				place.DrawSample(maskgc, foregroundcolor);

				# Figure out where to place the tip
				newpt.x = oldcenter.x - imgdev.GetWidth() / 2;
				newpt.y = oldcenter.y - imgdev.GetHeight() / 2;
				offset = newpt - point;

				# Show the tip
				datatip.SetImageTip(imgdev, maskdev, offset);
				return (1);
				}
			}

		layer = layer.NextLayer;
		}
	return (0);

	}

proc OnViewDataTipHidden (
   class GRE_VIEW view
   ) {
   # Insert code here
   }


Back Home ©MicroImages, Inc. 2008 Published in the United States of America
11th Floor - Sharp Tower, 206 South 13th Street, Lincoln NE 68508-2010   USA
Business & Sales: (402)477-9554  Support: (402)477-9562  Fax: (402)477-9559
Business info@microimages.com  Support support@microimages.com  Web webmaster@microimages.com

13 May 2008

page update: 13 Aug 07