home products news downloads documentation support gallery online maps resellers search
TNTmips Downloads Menu

HOME

CONTACT US

CURRENT RELEASE
  TNT 2013

DEVELOPMENT VERSION
  TNT 2014

TNTmips Pro
PRIOR RELEASES
  TNT 2012

FREE SOFTWARE
  TNTmips Free
  TNTatlas
  TNTsdk

MORE DOWNLOADS
  HASP Key Driver
  Screen Recorder
  TNT Language Kits
  Sample Geodata
  TNT Scripts

DOCUMENTATION
  TNTmips Tutorials
  Tutorial Datasets
  Technical Guides
  Scripts
  Quick Guides

MORE INFO
  Download FAQs
  FTP
  Download Managers
  Find Reseller

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. 2013 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

25 March 2009

page update: 26 May 11