MapWindow Developer Team : MapWindow Discussion Forum
Hi, there is an example of label generation for cities including label categories, priority of drawing, graduated colors. See the screenshot with results for USA cities here [www.mapwindow.org
Labeling US cities with new labeler
Posted by:
Sergei ()
Date: February 13, 2010 01:20PM
Hi,
there is an example of label generation for cities including label categories, priority of drawing, graduated colors. See the screenshot with results for USA cities here [www.mapwindow.org] (in attachment). See documentation of new methods here [www.mapwindow.org]. The methods and properties used here can be slightly changed. I'd like to port methods for labels/categories generation in labels class, for example.
Sergei
---------- The code (VB6) ------------
Edited 2 time(s). Last edit at 02/13/2010 01:31PM by Sergei.
there is an example of label generation for cities including label categories, priority of drawing, graduated colors. See the screenshot with results for USA cities here [www.mapwindow.org] (in attachment). See documentation of new methods here [www.mapwindow.org]. The methods and properties used here can be slightly changed. I'd like to port methods for labels/categories generation in labels class, for example.
Sergei
---------- The code (VB6) ------------
Private Sub GenerateLabelsForCities() Dim obj As Object Dim sf As MapWinGIS.Shapefile Dim lb As MapWinGIS.Labels Dim sMessage As String Dim iPosition As Integer Dim iField As Integer Dim iCount As Long Dim i As Integer ' the position of cities layer in the layers list (set appropriate value) iPosition = 2 ' getting shapefile obj = Map1.GetObject(Map1.LayerHandle(iPosition)) If TypeOf obj Is MapWinGIS.Shapefile Then Set sf = obj If sf Is Nothing Then MsgBox "Unable to retrieve shapefile with the position: " & iPosition Exit Sub End If ' asking the user for NAME field sMessage = "" For i = 0 To sf.NumFields - 1 sMessage = sMessage & i & " - " & sf.Field(i).Name & vbNewLine Next i iField = Val(InputBox(sMessage, "Enter the index of NAME field", "-1")) If iField < 0 Or iField >= sf.NumFields Then MsgBox "Invalid index of field", vbInformation Exit Sub End If ' label generation; it doesn't matter what method you'll specify for point shapefile ' there is the only one availible (maybe it'll better to add it to the list of constants) iCount = sf.GenerateLabels(iField, lpCenter) If Count = 0 Then MsgBox "No labels were generated", vbInformation Exit Sub End If ' we'll be using the class intensively so better to set a variable Set lb = sf.Labels ' changing alignment to see the point (will be used by all categories afterwards) lb.Alignment = laTopLeft ' generation of categories; such method can be used as well as sf.GenerateCategories ' here we won't be using automatically generated minValue maxValue for categories, ' so simply to add categories will be ok for us lb.ClearAllCategories For i = 1 To 7 lb.AddCategory("Category " & i) Next i ' setting ranges for population, font size and priority ' the categories with large values of priority will be darwn first (0 by default) With lb.Category(0) .MinValue = 0 ' population from 0 people .MaxValue = 10000 ' to 10000 people .FontSize = 10 .Priority = 1 End With With lb.Category(1) .MinValue = 10000 .MaxValue = 50000 .FontSize = 10 .Priority = 2 End With With lb.Category(2) .MinValue = 50000 .MaxValue = 100000 .FontSize = 10 .Priority = 3 End With With lb.Category(3) .MinValue = 100000 .MaxValue = 250000 .FontSize = 12 .Priority = 4 End With With lb.Category(4) .MinValue = 250000 .MaxValue = 500000 .FontSize = 13 .Priority = 5 End With With lb.Category(5) .MinValue = 500000 .MaxValue = 1000000 .FontSize = 14 .Priority = 6 .FontUnderline = True End With With lb.Category(6) .MinValue = 1000000 .MaxValue = 100000000 .FontSize = 18 .Priority = 7 .FontUnderline = True End With ' asking the user for POPULATION field iField = Val(InputBox(sMessage, "Enter the index of POPULATION field", "-1")) If iField < 0 Or iField >= sf.NumFields Then MsgBox "Invalid index of field", vbInformation Exit Sub End If ' the program needs to know values of what field should be compared ' to minValue maxValue properties of categories sf.ClassificationField = iField ' determining which labels belong to which category (see Label.Category property) sf.ApplyCategories ' setting graduated colors lb.SetGraduatedColors leFont, vbBlack, vbRed, True ' labels will be above all layers lb.VerticalPosition = vpAboveAllLayers ' setting halo for better visibility; we could set it for Labels class initially ' the category is initialized by the current settings of parent Labels class For i = 0 To lb.NumCategories - 1 lb.Category(i).HaloSize = 4 lb.Category(i).HaloColor = vbWhite lb.Category(i).HaloVisible = True Next i ' halo is darwn better in GDI sf.Labels.UseGdiPlus = False ' to see labels Map1.ShapeDrawingMethod = dmNewWithLabels ' refreshing the map Map1.Redraw End Sub
Edited 2 time(s). Last edit at 02/13/2010 01:31PM by Sergei.
Re: Labeling US cities with new labeler
Posted by:
pmeems ()
Date: February 16, 2010 08:32AM
Thanks Sergei for all your hard work.
Here are some screen shots.
Single layer:
Multiple layers:

Here are some screen shots.
Single layer:
Multiple layers:

Re: Labeling US cities with new labeler
Posted by:
Sergei ()
Date: March 22, 2010 08:13AM
Hi Brian,
sorry for the delayed answer, I haven't noticed your post.
Naturally I use GDI+ for transparency. New labels can be drawn in both GDI (which is faster) and GDI+ (which is nicer) modes. And they should work in the layout plug-in as long as labels are displayed on the map. If not - let me know.
1. The labels on the edges of the map aren't drawn... Well, the easy solution is just to enlarge bounds which you pass to the procedure and then return only a necessary part of the resulting bitmap. All labels will be there I expect. Of course, it's possible to extend only certain bounds. But some labels will be clipped inescapably.
To make it better I'd do the following:
- add read-only Height and Width properties to the Label class;
- add procedure void Labels::CalculateLabelSize(double scale);
- having label position and their size in pixels, it's quite easy to determine which one will fall into certain extents without clipping;
- then just set Label.Visible property to false for unwanted labels.
But perhaps it'd be easier to implement this logic in the drawing procedure itself. To make it more unified I'd add property ShowClippedLabels without specifing the side of the screen. Why side is critical to you?
2. As for scaling, I'd try Labels.BasicScale. It's possible to change the value, make a screenshot and return it back.
Sergei
sorry for the delayed answer, I haven't noticed your post.
Naturally I use GDI+ for transparency. New labels can be drawn in both GDI (which is faster) and GDI+ (which is nicer) modes. And they should work in the layout plug-in as long as labels are displayed on the map. If not - let me know.
1. The labels on the edges of the map aren't drawn... Well, the easy solution is just to enlarge bounds which you pass to the procedure and then return only a necessary part of the resulting bitmap. All labels will be there I expect. Of course, it's possible to extend only certain bounds. But some labels will be clipped inescapably.
To make it better I'd do the following:
- add read-only Height and Width properties to the Label class;
- add procedure void Labels::CalculateLabelSize(double scale);
- having label position and their size in pixels, it's quite easy to determine which one will fall into certain extents without clipping;
- then just set Label.Visible property to false for unwanted labels.
But perhaps it'd be easier to implement this logic in the drawing procedure itself. To make it more unified I'd add property ShowClippedLabels without specifing the side of the screen. Why side is critical to you?
2. As for scaling, I'd try Labels.BasicScale. It's possible to change the value, make a screenshot and return it back.
Sergei
Re: Labeling US cities with new labeler
Posted by:
bmarch ()
Date: March 22, 2010 02:58PM
Hi Sergei,
Thanks for the answer.
The layout engine is actually doing exactly what you describe. I find the biggest label. Figure out how big an overlap is needed and then request an extent such that the labels don't get cut off. The problem is it ends up rendering lots of map that just gets deleted when I finally glue the tiles all together.
I need to be able to specify a side so that tiles that are at the edge of the printed map wont have labels hanging of their edges.
I'll look at BasicScale.
Brian
Thanks for the answer.
The layout engine is actually doing exactly what you describe. I find the biggest label. Figure out how big an overlap is needed and then request an extent such that the labels don't get cut off. The problem is it ends up rendering lots of map that just gets deleted when I finally glue the tiles all together.
I need to be able to specify a side so that tiles that are at the edge of the printed map wont have labels hanging of their edges.
I'll look at BasicScale.
Brian
Re: Labeling US cities with new labeler
Posted by:
bmarch ()
Date: March 23, 2010 08:45AM
Hi Sergei,
I thought it would be a good idea to move this over here since we've gotten off topic and into development land.
Brian
I thought it would be a good idea to move this over here since we've gotten off topic and into development land.
Brian
Re: Labeling US cities with new labeler
Posted by:
Sergei ()
Date: March 25, 2010 03:08AM
Brian,
It seems unlogical to me to use tiles. Why not to generate the image of the necessary resolution at once? What are the limitations of ocx that prevent doing this?
Sergei
It seems unlogical to me to use tiles. Why not to generate the image of the necessary resolution at once? What are the limitations of ocx that prevent doing this?
Sergei
Re: Labeling US cities with new labeler
Posted by:
bmarch ()
Date: March 25, 2010 08:44AM
Hi Sergei,
The OCX doesn't seem to able to render to a bitmap big enough for printing. A 36inch X 36inch map has a resolution of 10800 X 10800 at 300PPI (Which is a minimum for printing, computer screens us 96PPI) thats 116.6 megapixels! The largest bitmap I've been able to get out of the OCX has been around 2000 X 2000 depending on how many layers are loaded. If you can think of another way to get the OCX to render at such a high resolution without using tiles I'd love to hear it.
Brian
The OCX doesn't seem to able to render to a bitmap big enough for printing. A 36inch X 36inch map has a resolution of 10800 X 10800 at 300PPI (Which is a minimum for printing, computer screens us 96PPI) thats 116.6 megapixels! The largest bitmap I've been able to get out of the OCX has been around 2000 X 2000 depending on how many layers are loaded. If you can think of another way to get the OCX to render at such a high resolution without using tiles I'd love to hear it.
Brian
Re: Labeling US cities with new labeler
Posted by:
Sergei ()
Date: March 25, 2010 01:51PM
And what happened when you tried to get higher resolution?
Re: Labeling US cities with new labeler
Posted by:
bmarch ()
Date: March 25, 2010 04:19PM
Hey Sergei,
Well actually it just returned a null object. No error message or anything, but the image object that I got back from the snapshot function was null. Lowering the size of the image to something smaller fixed it and I started getting proper bitmaps back. After talking with Chris (or Ted) about it a bit we concluded that a tiling scheme would probably be the simplest solution. But if you know of a way to get the OCX to render to a bitmap that big please let me know. If not then lets start considering getting the labels to show up without needing the big overlap.
Brian
Well actually it just returned a null object. No error message or anything, but the image object that I got back from the snapshot function was null. Lowering the size of the image to something smaller fixed it and I started getting proper bitmaps back. After talking with Chris (or Ted) about it a bit we concluded that a tiling scheme would probably be the simplest solution. But if you know of a way to get the OCX to render to a bitmap that big please let me know. If not then lets start considering getting the labels to show up without needing the big overlap.
Brian
Re: Labeling US cities with new labeler
Posted by:
Sergei ()
Date: March 26, 2010 01:07PM
Brian,
Ok, I'll take a look at the problem when I have some spare time (perhaps in the next week). Something can be done with it I think.
Sergei
Ok, I'll take a look at the problem when I have some spare time (perhaps in the next week). Something can be done with it I think.
Sergei
Re: Labeling US cities with new labeler
Posted by:
Sergei ()
Date: March 28, 2010 09:44AM
I've worked with it a bit. There is a problem indeed to return the large image form the MapWinGis. The largest screenshot I was able to get is 11300 X 8600 pixels, which takes 277 MB on the HDD. Also I succeeded in creating a DIBSection bitmap of larger size, but couldn't pass it to the image class. It's strange but in both cases I ended up approaching 600 Mb of RAM usage for the application. After it I couldn't allocate more memory with GDI functions or new calls. But I got 2 GB of RAM and didn't approach the limit.
The largest image I was able to save with the simple code below (C#) is 556 MB of size :
So there is question: what is preventing to allocate more?
I have no answer for it now. Can anybody try the code on the other PC?
Sergei
The largest image I was able to save with the simple code below (C#) is 556 MB of size :
MapWinGIS.Image img = new MapWinGIS.Image(); if (img.CreateNew(15000, 13010)) { img.Save("e:\\snapshot.bmp", false, ImageType.BITMAP_FILE, null); }
So there is question: what is preventing to allocate more?
I have no answer for it now. Can anybody try the code on the other PC?
Sergei
Re: Labeling US cities with new labeler
Posted by:
bmarch ()
Date: March 29, 2010 08:20AM
Hi Sergei,
Thanks for looking at this more for me. I've never managed to get it to save any image close to that big before. It also seems to be dependent on the number of layers you have loaded and how big they are. Which is why we stated this whole tiling business to begin with.
I was thinking, for the printing code, I don't absolutely need a MapWinGIS.Image file. (Since I save it to disc and close it anyways) If we could get the OCX to render at higher resolution to a DIB then we can save it to disc as a BMP and then I could just pass a filename into the snapshot function and then open the file later. Alternatively it could return a DIB as an object and I could try converting it into something that .NET can handle. It would really speed of printing I think If I could avoid writing the Map to disc every time I render it.
Also Sergei, I'm not sure that this is going to solve our problem anyways. Ted and I have not managed to create Bitmap objects in .NET that are larger than 8000x8000. So even if we manage to get the OCX to write to a bitmap thats bigger than that we won't be able to load it so that we can print from it.
Do you think it would be possible to pass a .NET graphics object into the OCX and have it draw to that? That way we wouldn't really be dealing with bitmaps any more but graphics objects which would keep all the vector data as vectors and could one day be extended to allow for printing to layered PDF's. Thats Paul Meeme's dream I think = )
Brian
Edited 3 time(s). Last edit at 03/29/2010 10:00AM by bmarch.
Thanks for looking at this more for me. I've never managed to get it to save any image close to that big before. It also seems to be dependent on the number of layers you have loaded and how big they are. Which is why we stated this whole tiling business to begin with.
I was thinking, for the printing code, I don't absolutely need a MapWinGIS.Image file. (Since I save it to disc and close it anyways) If we could get the OCX to render at higher resolution to a DIB then we can save it to disc as a BMP and then I could just pass a filename into the snapshot function and then open the file later. Alternatively it could return a DIB as an object and I could try converting it into something that .NET can handle. It would really speed of printing I think If I could avoid writing the Map to disc every time I render it.
Also Sergei, I'm not sure that this is going to solve our problem anyways. Ted and I have not managed to create Bitmap objects in .NET that are larger than 8000x8000. So even if we manage to get the OCX to write to a bitmap thats bigger than that we won't be able to load it so that we can print from it.
Do you think it would be possible to pass a .NET graphics object into the OCX and have it draw to that? That way we wouldn't really be dealing with bitmaps any more but graphics objects which would keep all the vector data as vectors and could one day be extended to allow for printing to layered PDF's. Thats Paul Meeme's dream I think = )
Brian
Edited 3 time(s). Last edit at 03/29/2010 10:00AM by bmarch.
Re: Labeling US cities with new labeler
Posted by:
Sergei ()
Date: March 29, 2010 10:09AM
Brian,
to save the bitmap directly to the disk not using Image class is the idea I like. Creating image class means double use of RAM and even more because of some inoptimalities.
The other limitation is the usage of CreateDiscardableBitmap or CreateCompatibleBitmap functions. If I understand it right the size of the DDB bitmap created by them is limited by the video memory (256 MB on my PC). And indeed the function returned false when I requested larger bitmaps.
To draw larger bitmaps I used CreateDIBSection function. What is needed now is to store such bitmap to the HDD without using Image class. I'll try to do it the next time. I guess that 400-500 MB bitmap is enough for your purposes?
After reading your edits:
I thought you got no limitation in .NET. If they exist then indeed writing to HDD isn't the best solution. Passing .NET graphics object to ActiveX - sounds unreal. But I'll try to google something ;)
Sergei
Edited 1 time(s). Last edit at 03/29/2010 10:18AM by Sergei.
to save the bitmap directly to the disk not using Image class is the idea I like. Creating image class means double use of RAM and even more because of some inoptimalities.
The other limitation is the usage of CreateDiscardableBitmap or CreateCompatibleBitmap functions. If I understand it right the size of the DDB bitmap created by them is limited by the video memory (256 MB on my PC). And indeed the function returned false when I requested larger bitmaps.
To draw larger bitmaps I used CreateDIBSection function. What is needed now is to store such bitmap to the HDD without using Image class. I'll try to do it the next time. I guess that 400-500 MB bitmap is enough for your purposes?
After reading your edits:
I thought you got no limitation in .NET. If they exist then indeed writing to HDD isn't the best solution. Passing .NET graphics object to ActiveX - sounds unreal. But I'll try to google something ;)
Sergei
Edited 1 time(s). Last edit at 03/29/2010 10:18AM by Sergei.
Re: Labeling US cities with new labeler
Posted by:
Sergei ()
Date: March 29, 2010 01:00PM
Brian,
It seems to be working. I've drawn a line on the .NET form from MapWinGis. Can you pass window handle of the layout control (System.IntPtr) in such way?
It seems to be working. I've drawn a line on the .NET form from MapWinGis. Can you pass window handle of the layout control (System.IntPtr) in such way?
------------MapWinGis-------------
STDMETHODIMP CImageClass::DrawToNetWindow(int** hWnd)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HWND hWND = (HWND)hWnd;
HDC hdc = GetDC(hWND);
if (!hdc)
{
return S_OK;
}
MoveToEx(hdc, 0,0, NULL);
LineTo(hdc, 100, 100);
return S_OK;
}
------------Client C#-------------
private void button1_Click(object sender, EventArgs e)
{
MapWinGIS.Image img = new MapWinGIS.Image();
img.DrawToNetGraphics(this.Handle);
}
SergeiRe: Labeling US cities with new labeler
Posted by:
bmarch ()
Date: March 29, 2010 02:20PM
Hi Sergei,
That looks promising, I'm not drawing directly to a form though, I'm drawing to a graphics object which might have originated as a form, bitmap or printer. What if I get the graphic object's HDC and send that to the OCX as a IntPtr. We could pass the extent, resolution (int width) and HDC into the ocx and have it do the drawing and return.
As a test we can do:
-----C#-----
private void TestDraw(Graphics g)
{
IntPtr HDC = g.GetHdc();
m_Map.SnapShot4(extent, width, HDC);
}
Brian
That looks promising, I'm not drawing directly to a form though, I'm drawing to a graphics object which might have originated as a form, bitmap or printer. What if I get the graphic object's HDC and send that to the OCX as a IntPtr. We could pass the extent, resolution (int width) and HDC into the ocx and have it do the drawing and return.
As a test we can do:
-----C#-----
private void TestDraw(Graphics g)
{
IntPtr HDC = g.GetHdc();
m_Map.SnapShot4(extent, width, HDC);
}
Brian
Re: Labeling US cities with new labeler
Posted by:
Sergei ()
Date: March 29, 2010 06:10PM
Brian,
it works in such way as well (C#). But problems are possible. For example I got System.InvalidOperationException: 'Object is currently in use elsewhere' for the first version of my code. I'll try to write SnapShot4 function with the parameters you suggested, then will see how it works ;)
Sergei
it works in such way as well (C#). But problems are possible. For example I got System.InvalidOperationException: 'Object is currently in use elsewhere' for the first version of my code. I'll try to write SnapShot4 function with the parameters you suggested, then will see how it works ;)
private void Form1_Paint(object sender, PaintEventArgs e)
{
MapWinGIS.Image img = new MapWinGIS.Image();
img.DrawToNetGraphics(e.Graphics.GetHdc());
}
Sergei
Re: Labeling US cities with new labeler
Posted by:
bmarch ()
Date: April 08, 2010 02:13PM
Hi Sergei,
I had an idea, instead of trying to get a DC from a GDI+ graphics object. What if we drew to a WMF or EMF or EMF+ that way we could still write it do disc but when I loaded it up in .NET it would preserve all of the vector information as vectors?
What do you think?
Brian
I had an idea, instead of trying to get a DC from a GDI+ graphics object. What if we drew to a WMF or EMF or EMF+ that way we could still write it do disc but when I loaded it up in .NET it would preserve all of the vector information as vectors?
What do you think?
Brian
Re: Labeling US cities with new labeler
Posted by:
Sergei ()
Date: April 09, 2010 01:09AM
Good idea too. You have no problems with scaling of lines and labels in this case I suppose. But still the idea with the drawing direct to DC is worth trying. I'll be busy with the image resampling for several more days. After it I'll return to this problem.
Sergei
Sergei
Re: Labeling US cities with new labeler
Posted by:
Sergei ()
Date: April 24, 2010 05:09PM
Brian,
I found the time at last to write Map.SnapShotToDC ;) It draws the map on the form or picturebox quite good. I tried to set width = 20000 and it works ok, but it can be misguiding, as actually only a small portion of this huge bitmap is drawn. Perhaps I'll add code for scaling of lines and labels to the procedure as well. Most likely I'll commit the changes tomorrow.
Also could you shift this discussion to separate topic? It has little to do with labeling ;)
Sergei
Edited 1 time(s). Last edit at 04/24/2010 05:12PM by Sergei.
I found the time at last to write Map.SnapShotToDC ;) It draws the map on the form or picturebox quite good. I tried to set width = 20000 and it works ok, but it can be misguiding, as actually only a small portion of this huge bitmap is drawn. Perhaps I'll add code for scaling of lines and labels to the procedure as well. Most likely I'll commit the changes tomorrow.
Also could you shift this discussion to separate topic? It has little to do with labeling ;)
Sergei
Edited 1 time(s). Last edit at 04/24/2010 05:12PM by Sergei.
Re: Labeling US cities with new labeler
Posted by:
bmarch ()
Date: March 15, 2010 09:02AM
Hey,
Those look absolutely great, how did you get an alpha channel to work in GDI? I thought only GDI+ supported it.
Paul by any chance does this work in my layout plug-in or is that going to need to be updated?
Sergei I have a technical question for you:
The print layout plug-in that I developed uses the SnapShot3(...) method to capture images from the OCX so that they can be printed from .NET Because of limits in the OCX I have to call SnapShot3(...) multiple times in order to generate a single high resolution image to print with. The problem is that labels that are on the edges of these images aren't drawn. Since you are digging around in the drawing code already, would it be possible to modify the SnapShot3(...) code so that labels that overlap with the edge of the image are still drawn, but only on select Edges. Something like this.
SnapShot4(double MapGeoWidth, int pixelHeight, int pixelWidth, bool labelTop, bool labelBottom, labelLeft, labelRight)
Which would return a screen shot of the given extent at the resolution needed but only have labels hanging off the edges corresponding to the booleans given.
What do you think, can it be done? If I'm not clear please let me know.
Another technical questions would it be possible to also add a variable to SnapShot method that would draw all the labels scaled by a certain factor, but just for that one screen shot. At the moment I'm doing some ugly stuff to get the labels to draw nicely at 300DPI instead of 96DPI, I'm actually changing all of the label point sizes calling SnapShot3(...) and then changing them all back.
Brian M.
Edited 1 time(s). Last edit at 03/15/2010 09:05AM by bmarch.
Those look absolutely great, how did you get an alpha channel to work in GDI? I thought only GDI+ supported it.
Paul by any chance does this work in my layout plug-in or is that going to need to be updated?
Sergei I have a technical question for you:
The print layout plug-in that I developed uses the SnapShot3(...) method to capture images from the OCX so that they can be printed from .NET Because of limits in the OCX I have to call SnapShot3(...) multiple times in order to generate a single high resolution image to print with. The problem is that labels that are on the edges of these images aren't drawn. Since you are digging around in the drawing code already, would it be possible to modify the SnapShot3(...) code so that labels that overlap with the edge of the image are still drawn, but only on select Edges. Something like this.
SnapShot4(double MapGeoWidth, int pixelHeight, int pixelWidth, bool labelTop, bool labelBottom, labelLeft, labelRight)
Which would return a screen shot of the given extent at the resolution needed but only have labels hanging off the edges corresponding to the booleans given.
What do you think, can it be done? If I'm not clear please let me know.
Another technical questions would it be possible to also add a variable to SnapShot method that would draw all the labels scaled by a certain factor, but just for that one screen shot. At the moment I'm doing some ugly stuff to get the labels to draw nicely at 300DPI instead of 96DPI, I'm actually changing all of the label point sizes calling SnapShot3(...) and then changing them all back.
Brian M.
Edited 1 time(s). Last edit at 03/15/2010 09:05AM by bmarch.
Sorry, only registered users may post in this forum.


