Arabic Lang Problem

Topics: SharpMap v2.0
Apr 6, 2008 at 6:19 PM
hii all
I am using SharpMap to display Street Map
but I want to display Labels in Arabic Lang.
May 9, 2008 at 2:56 PM
Edited May 9, 2008 at 2:59 PM
i have this problem soo in farsi lang
nobody idea?????
Coordinator
May 9, 2008 at 5:44 PM
Labels will display in whatever language they are stored in.

Are you having trouble displaying them at all or do they display, but look wrong?
May 9, 2008 at 8:44 PM
my problem solved
SharpMap.Layers.VectorLayer province = new SharpMap.Layers.VectorLayer("Province");
ShapeFile provinceshp = new ShapeFile(Server.MapPath(@"~/App_Data/province.shp"), true);
provinceshp.Encoding = System.Text.Encoding.Default;
province.DataSource = provinceshp;
show wrong

but i have new problem in label
if set LabelLayer for multypolygone layers
show many label for any polygone
May 12, 2008 at 5:11 AM


codekaizen wrote:
Labels will display in whatever language they are stored in.

Are you having trouble displaying them at all or do they display, but look wrong?


hi, codekaizen.
i also has this problem. i can read and display label. but, some of the labels can not display fully. for example, one of the labels name is "china", but it just display "ch" or even display none. When i zoom in or zoom out, it can display normally.
can you help me ? thanks :-)
Coordinator
May 12, 2008 at 9:14 AM
Hi cdgrain, is this a problem when your map is made up of tiles?

If so it is likely to be due to the fact that the feature being labelled is on one tile but the label text spans two tiles. In the past to overcome a similar issue we modified the data provider to buffer query extent of the data.

The collision testing on the labels can also impact this - one 'logical label' may have two different priorities on adjacent tiles due to other features and be purged on one and allowed on another - again buffering the data helps smooth this out but discrepancies do still arise
May 13, 2008 at 1:56 AM
Edited May 13, 2008 at 1:58 AM
Hi JohnDiss. yes, it is just the problem of your description. my god, the tiles also have different priorities.
but, i don't understand your meaning of "modified the data provider to buffer query extent of the data" maybe for my poor english.
Can you describe it more detailed? thanks a lot. :-)
Coordinator
May 13, 2008 at 9:15 AM
Edited May 13, 2008 at 12:14 PM
Hi again cdgrain, there are a few options: perhaps make a proxy class which implements IProvider and contains the real provider you are using (I guess shapefile). in your new classes implementation of ExecuteIntersectionQuery(BoundingBox buffer) expand the buffer  before passing it down to the real provider.
so your proxy might look something like :

public class BufferedDataProviderProxy<TRealProvider> : IProvider
where TRealProvider : IProvider
{
    private double _bufferScaleFactor = 1;
    public double BufferScaleFactor
    {
        get{return _bufferScaleFactor;}
        set{_bufferScaleFactor=value;}
    }
    private TRealProvider _realProvider;
    public TRealProvider RealProvider 
    {
        get
        {
            return _realProvider;
        }
    }
      public BufferedDataProviderProxy(TRealProvider realProvider)
    {
        _realProvider = realProvider;
    }

    public void ExceuteIntersectionQuery(BoundingBox box, FeatureDataSet ds)
    {
        BoundingBox bufferedBox = box.Clone().Expand(BufferScaleFactor); 
        /*i cant remember if there is an expand method on BoundingBox - 
          if not you will need to create your own*/
        RealProvider.ExecuteIntersectionQuery(bufferedBox, ds);
        
    }

  ..../* more stuff to implement to satisfy IProvider - 
        just relay the calls to the RealProvider */


    
}

note this code is incomplete/ untested/  and written without reference to the interfaces concerned but hopefully it will give you an idea about how to do it

HTH jd
May 13, 2008 at 1:32 PM
Hi JohnDiss. thank you for your code.

i will try it. :)
May 21, 2008 at 7:14 AM
Hi again JohnDiss
But, I still can not understand your code.
BoundingBox bufferedBox = box.Clone().Expand(BufferScaleFactor);
// why should we to expand the box. but, there is not Expand() method in sharpmap.
RealProvider.ExecuteIntersectionQuery(bufferedBox, ds);
//use this intersection query. how does it solve the collision of different priority of label ? Could you help me further ? thanks a lot. :)
Coordinator
May 21, 2008 at 9:48 AM
Edited May 21, 2008 at 9:57 AM
Hi again cdgrain, the primary purpose of expanding the box is to draw a label for a feature who's point is near the edge of an adjacent tile - in your example above it is to get the "ina" part of china renderered onto the tile even though the actual point is not on the same tile.

the second problem arises that perhaps you have a secondary town label part of which is drawn on tile "A", collision detection on tile "A" allowed the label to be drawn. On the adjacent tile "B" you wish to draw the remainder of the label, but on this tile it would overlap the label for a primary town, so it is culled. In this case you still have only a partial label for the feature. By expanding the query box you stand more chance that the nearby primary features will cull the secondary ones more evenly. Depending on the actual dataset we have found that a value between 1.5 and 3 times the real bounds works reasonably well but you can find that label cropping still occurs. This is dependent on things like feature density and the average length of the feature name. In the UK it is particulary apparent with things like welsh town / villiage names which can easily span 3 tiles anyway.. I will try and complete the code and post it later.. HTH jd
Coordinator
May 21, 2008 at 7:44 PM

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
using SharpMap.Geometries;

namespace SharpMap.Data.Providers
{
    public class BufferedDataProviderProxy<TRealProvider>
        : IProvider
        where TRealProvider : IProvider
    {
        public BufferedDataProviderProxy(TRealProvider realProvider)
            : this(realProvider, 1.0)
        { }

        public BufferedDataProviderProxy(TRealProvider realProvider, double bufferScaleFactor)
        {
            this.RealProvider = realProvider;
            this.BufferScaleFactor = bufferScaleFactor;

        }

        TRealProvider _realProvider;
        /// <summary>
        /// Returns the real provider being proxied.
        /// </summary>
        public TRealProvider RealProvider
        {
            get
            {
                return _realProvider;
            }
            private set
            {
                _realProvider = value;
            }
        }

        private double _bufferScaleFactor;
        /// <summary>
        /// The scale factor we are multiplying the box by.
        /// A scale factor &gt; 1.0 will expand the BoundingBox used in ExecuteIntersectionQuery
        /// &lt; 1.0 will shrink the BoundingBox
        /// </summary>
        public double BufferScaleFactor
        {
            get { return _bufferScaleFactor; }
            set { _bufferScaleFactor = value; }
        }

        #region IProvider Members

        /// <summary>
        /// returns a BoundingBox whos width and height are
        /// scaled by BufferScaleFactor
        /// </summary>
        /// <param name="box"></param>
        /// <returns></returns>
        private BoundingBox ExpandBox(BoundingBox box)
        {
            double dx = (box.Width / 2) * BufferScaleFactor;
            double dy = (box.Height / 2) * BufferScaleFactor;

            Point p = box.GetCentroid();
            return new BoundingBox(
                p.X - dx,
                p.Y - dy,
                p.X + dx,
                p.Y + dy);

        }

        public Collection<Geometry> GetGeometriesInView(BoundingBox bbox)
        {
            return RealProvider.GetGeometriesInView(ExpandBox(bbox));
        }

        public Collection<uint> GetObjectIDsInView(BoundingBox bbox)
        {
            return RealProvider.GetObjectIDsInView(ExpandBox(bbox));
        }

        public Geometry GetGeometryByID(uint oid)
        {
            return RealProvider.GetGeometryByID(oid);
        }

        public void ExecuteIntersectionQuery(Geometry geom, FeatureDataSet ds)
        {
            /* Buffer is not implemented in any of the Geometries
             * so we will just relay to the real provider.
             * Alternatively you could use NTS to buffer properly.
             */
            RealProvider.ExecuteIntersectionQuery(geom, ds);
        }

        public void ExecuteIntersectionQuery(BoundingBox box, FeatureDataSet ds)
        {
            RealProvider.ExecuteIntersectionQuery(ExpandBox(box), ds);
        }

        public int GetFeatureCount()
        {
            return RealProvider.GetFeatureCount();
        }

        public FeatureDataRow GetFeature(uint RowID)
        {
            return RealProvider.GetFeature(RowID);
        }

        public BoundingBox GetExtents()
        {
            return RealProvider.GetExtents();
        }

        public string ConnectionID
        {
            get { return RealProvider.ConnectionID; }
        }

        public void Open()
        {
            RealProvider.Open();
        }

        public void Close()
        {
            RealProvider.Close();
        }

        public bool IsOpen
        {
            get { return RealProvider.IsOpen; }
        }

        public int SRID
        {
            get
            {
                return RealProvider.SRID;
            }
            set
            {
                RealProvider.SRID = value;
            }
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            RealProvider.Dispose();
        }

        #endregion
    }
}

Coordinator
May 21, 2008 at 7:49 PM
Edited May 21, 2008 at 7:51 PM
Then in use:
 
            LabelLayer l = new LabelLayer("myLayer");
            l.DataSource = new BufferedDataProviderProxy<ShapeFile>(
                new ShapeFile("myshapefile.shp", true), 1.5);  

HTH jd
May 23, 2008 at 1:54 AM
Hi JohnDiss
your code is so amazing. the problem has been solved under the help of your code. But, a small part feature label cropping still occurs for the high density. My feature name is chinese coding. so the length of label is unlike the welsh town :). And I feel happy that you have been added this proxy class to the source code item.
by the way, the efficiency of SharpMap can meet the requirement of actual project ? I just do a test and learn the principle of GIS.
Coordinator
May 23, 2008 at 9:00 AM
Edited May 23, 2008 at 9:01 AM
Glad it helped, as per efficiency, as long as you are careful with scale thresholds, i.e not rendering street level data at world level you should be fine. It is in production use in many different fields, you get the source code and can modify it as required and its free!  Good luck jd