Lucene.Net  3.0.3
Lucene.Net is a port of the Lucene search engine library, written in C# and targeted at .NET runtime users.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
SpatialArgsParser.cs
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 using System;
19 using System.Collections.Generic;
20 using System.Text;
21 using Spatial4n.Core.Context;
22 using Spatial4n.Core.Io;
23 using Spatial4n.Core.Shapes;
24 
25 namespace Lucene.Net.Spatial.Queries
26 {
27  public class SpatialArgsParser
28  {
29  public const String DIST_ERR_PCT = "distErrPct";
30  public const String DIST_ERR = "distErr";
31 
32  /// <summary>
33  /// Writes a close approximation to the parsed input format.
34  /// </summary>
35  /// <param name="args"></param>
36  /// <returns></returns>
37  public static String WriteSpatialArgs(SpatialArgs args)
38  {
39  var str = new StringBuilder();
40  str.Append(args.Operation.GetName());
41  str.Append('(');
42  str.Append(args.Shape);
43  if (args.DistErrPct != null)
44  str.Append(" distErrPct=").Append(String.Format("{0:0.00}%", args.DistErrPct*100d));
45  if (args.DistErr != null)
46  str.Append(" distErr=").Append(args.DistErr);
47  str.Append(')');
48  return str.ToString();
49  }
50 
51  /// <summary>
52  /// Parses a string such as "Intersects(-10,20,-8,22) distErrPct=0.025".
53  /// </summary>
54  /// <param name="v"></param>
55  /// <param name="ctx"></param>
56  /// <returns></returns>
57  public SpatialArgs Parse(String v, SpatialContext ctx)
58  {
59  int idx = v.IndexOf('(');
60  int edx = v.LastIndexOf(')');
61 
62  if (idx < 0 || idx > edx)
63  {
64  throw new ArgumentException("missing parens: " + v);
65  }
66 
67  SpatialOperation op = SpatialOperation.Get(v.Substring(0, idx).Trim());
68 
69  //Substring in .NET is (startPosn, length), But in Java it's (startPosn, endPosn)
70  //see http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#substring(int, int)
71  String body = v.Substring(idx + 1, edx - (idx + 1)).Trim();
72  if (body.Length < 1)
73  {
74  throw new ArgumentException("missing body : " + v);
75  }
76 
77  Shape shape = new ShapeReadWriter(ctx).ReadShape(body);
78  var args = new SpatialArgs(op, shape);
79 
80  if (v.Length > (edx + 1))
81  {
82  body = v.Substring(edx + 1).Trim();
83  if (body.Length > 0)
84  {
85  Dictionary<String, String> aa = ParseMap(body);
86  args.DistErrPct = ReadDouble(aa["distErrPct"]); aa.Remove(DIST_ERR_PCT);
87  args.DistErr = ReadDouble(aa["distErr"]); aa.Remove(DIST_ERR);
88  if (aa.Count != 0)
89  {
90  throw new ArgumentException("unused parameters: " + aa);
91  }
92  }
93  }
94  args.Validate();
95  return args;
96  }
97 
98  protected static double? ReadDouble(String v)
99  {
100  double val;
101  return double.TryParse(v, out val) ? val : (double?)null;
102  }
103 
104  protected static bool ReadBool(String v, bool defaultValue)
105  {
106  bool ret;
107  return bool.TryParse(v, out ret) ? ret : defaultValue;
108  }
109 
110  /// <summary>
111  /// Parses "a=b c=d f" (whitespace separated) into name-value pairs. If there
112  /// is no '=' as in 'f' above then it's short for f=f.
113  /// </summary>
114  /// <param name="body"></param>
115  /// <returns></returns>
116  protected static Dictionary<String, String> ParseMap(String body)
117  {
118  var map = new Dictionary<String, String>();
119  int tokenPos = 0;
120  var st = body.Split(new[] {' ', '\n', '\t'}, StringSplitOptions.RemoveEmptyEntries);
121  while (tokenPos < st.Length)
122  {
123  String a = st[tokenPos++];
124  int idx = a.IndexOf('=');
125  if (idx > 0)
126  {
127  String k = a.Substring(0, idx);
128  String v = a.Substring(idx + 1);
129  map[k] = v;
130  }
131  else
132  {
133  map[a] = a;
134  }
135  }
136  return map;
137  }
138 
139  }
140 }