I am trying to use the offline mode of OSMdroid in an android.support.v4.app.Fragment.
My tiles are donwloaded by MOBAC using the "OSMdroid Zip" format around the coordinate 0,0 of the globe (it's just sea, but I just want something to show up as a beginning).
My zip file is locates in /sdcard/osmdroid/MapquestOSM.zip, and contains the folder MapQuest, which contains himself all the tiles in subfolders with numbers as names, from zoom 11 to zoom 16. The tiles are png files and have the extension ".png". Note that the /sdcard//osmdroid folder only contains my zip file.
My problem is that I see only an empty map, which is an empty grey grid.
public class ContactMapFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
return inflater.inflate(R.layout.map_fragment, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
MapView map = (MapView) getActivity().findViewById(R.id.mapview);
map.setBuiltInZoomControls(true);
map.getController().setZoom(11);
map.getController().setCenter(new GeoPoint(0,0));
map.setClickable(true);
map.setUseDataConnection(false);
map.setMaxZoomLevel(16);
map.setMinZoomLevel(11);
map.setTileSource(new XYTileSource("MapQuest",
ResourceProxy.string.offline_mode, 11, 16, 256, ".jpg", new String[] {
"http://otile1.mqcdn.com/tiles/1.0.0/map/",
"http://otile2.mqcdn.com/tiles/1.0.0/map/",
"http://otile3.mqcdn.com/tiles/1.0.0/map/",
"http://otile4.mqcdn.com/tiles/1.0.0/map/"}));
}
}
Using osmdroid-android-4.2 and slf4j-api-1.7.10
Permissions are :
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.READ_LOGS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE"/>
So I have two questions : Why is nothing displayed ? What are the urls in the XYTileSource supposed to point to (I found these urls on a tutorial) ?
Here is the solution I have finally used, it's working. If I remember well, you don't have to care about the zip file name, although I'm not sure it's true.
private void createMap(){
map = (MapView) getActivity().findViewById(R.id.mapview);
//first parameter indicates the folder inside the zip file containing the atlas.
String atlasName = "MapQuest";
String atlasExtension = ".png";
int tileSizePixels = 256;
int defaultLatitude = 400000000;
int defaultLongitude = 20000000;
int minZoom = 11;
int maxZoom = 17;
int defaultZoom = 14;
map.setTileSource(new XYTileSource(atlasName, ResourceProxy.string.mapquest_osm, minZoom, maxZoom, tileSizePixels, atlasExtension, new String[] {}));
map.setBuiltInZoomControls(true);
map.getController().setZoom(defaultZoom);
map.setClickable(true);
map.getController().setCenter(new GeoPoint(defaultLatitude, defaultLongitude));
}
Inside the zip file are the tiles stored in a .png format.
Hope it will help.
Related
<p:outputPanel id="panel">
<ui:repeat value="#{dataController.display()}"
var="item" rendered="#{Bean.showtable}">
<b:row>
<b:column col-md="5">
<h:outputText value="#{item.name}" style="font-family: verdana;font-size:16px;margin-bottom:15px;"></h:outputText>
</b:column>
<b:column col-md="7">
<h:inputText style="width:200px;height:30px;margin-bottom:15px;"
autocomplete="off"></h:inputText>
</b:column>
</b:row>
</ui:repeat>
In the above code, I have used ui:repeat for displaying the names of the items in a list in output text alongwith the input text for entering the values of the items.
The input text depends on the values in the list i.e dynamically generated.
I need to access the values from the input text and add them to List.
Can anyone please suggest me an approach to access the values from input text to bean/list despite using ui:repeat once to display the input text?
I have tried to create an empty list and again using ui:repeat only for input text.. tried to access values from input text.But ui:repeat doesnot work again.. as it was already used once for displaying.
I am new to JSF.Any help would be appreciated.Thankyou.
Don't use empty list. Initialize it with null or empty values.
Let's say we have inputs as your list, your bean should look like this.
#Named
#ViewScoped
public class DataController implements Serializable {
private List<String> inputs;
// getters and setters
#PostConstruct
public void init() {
inputs = new ArrayList<String>();
}
public List<Bean> getDisplay() {
List<Bean> display = new ArrayList<Bean>();
// add values to display
for (int i = inputs.size(); i < display.size(); i++) {
inputs.add("");
}
return display;
}
// for testing inputs
public void testInputs() {
for (String input : inputs) {
System.out.println(">>>>>" + input);
}
}
}
xhtml
<ui:repeat value="#{dataController.display()}" varStatus="idx" ...>
...
<h:inputText value="#{dataController.inputs[idx.index]}" style="width:200px;height:30px;margin-bottom:15px;" autocomplete="off"></h:inputText>
...
</ui:repeat>
<p:commandButton value="Test Inputs" action="#{dataController.testInputs}" update="#form" />
Hope this helps.
I'm having a Sitecore 8 MVC solution, and I have to extend the behavior of Data Source. It's pretty similar to what other people have done with queryable datasources before (such as http://www.cognifide.com/blogs/sitecore/reduce-multisite-chaos-with-sitecore-queries/ etc), but I've hooked into the <mvc.getXmlBasedLayoutDefinition> pipeline instead. It works fine and my custom data sources are resolved as they are entered in the layouts field on an item or on standard values.
But, when the custom data source is specified as a default data source on a rendering item, things becomes a bit trickier. I could solve it through the same pipeline, but that solution didn't look very nice. It means I'd have to load each rendering that hasn't a data source specified in the layout, and do the processing and resolve it from there. There must be a more natural way of doing this.
Does anyone know where to put such implementation logic for the default data source? (The <resolveRenderingDatasource> pipeline looked promising, but didn't execute in this scenario)
From what I understand, you may want to extend XmlBasedRenderingParser class. Here are the steps that should do the trick:
Create a new file App_Config\include\Sitecore.Mvc.Custom.config:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<initialize>
<processor
patch:after="processor[#type='Sitecore.Mvc.Pipelines.Loader.InitializeRoutes, Sitecore.Mvc']"
type="My.Assembly.Namespace.RegisterCustomXmlBasedRenderingParser, My.Assembly"/>
</initialize>
</pipelines>
</sitecore>
</configuration>
Create CustomXmlBasedRenderingParser class:
using Sitecore;
using Sitecore.Data.Items;
using Sitecore.Mvc.Extensions;
using Sitecore.Mvc.Presentation;
namespace My.Assembly.Namespace
{
public class CustomXmlBasedRenderingParser : XmlBasedRenderingParser
{
protected override void AddRenderingItemProperties(Rendering rendering)
{
RenderingItem renderingItem = rendering.RenderingItem;
if (renderingItem != null && !rendering.DataSource.ContainsText())
{
rendering.DataSource = ResolveRenderingItemDataSource(renderingItem);
}
base.AddRenderingItemProperties(rendering);
}
private static string ResolveRenderingItemDataSource(RenderingItem renderingItem)
{
string dataSource = string.Empty;
if (renderingItem.DataSource != null && renderingItem.DataSource.StartsWith("query:"))
{
string query = renderingItem.DataSource.Substring("query:".Length);
Item contextItem = Context.Item;
Item queryItem = contextItem.Axes.SelectSingleItem(query);
if (queryItem != null)
{
dataSource = queryItem.Paths.FullPath;
}
}
return dataSource;
}
}
}
Create RegisterCustomXmlBasedRenderingParser class:
using Sitecore.Mvc.Configuration;
using Sitecore.Mvc.Presentation;
using Sitecore.Pipelines;
namespace My.Assembly.Namespace
{
public class RegisterCustomXmlBasedRenderingParser
{
public virtual void Process(PipelineArgs args)
{
MvcSettings.RegisterObject<XmlBasedRenderingParser>(() => new CustomXmlBasedRenderingParser());
}
}
}
What is more, if you want your code to be executed for DataSource defined on both Rendering and Presentation Details, you should be able to use the code below:
using System.Xml.Linq;
using Sitecore;
using Sitecore.Data.Items;
using Sitecore.Mvc.Presentation;
namespace My.Assembly.Namespace
{
public class CustomXmlBasedRenderingParser : XmlBasedRenderingParser
{
public override Rendering Parse(XElement node, bool parseChildNodes)
{
Rendering rendering = base.Parse(node, parseChildNodes);
ResolveRenderingItemDataSource(rendering);
return rendering;
}
private static void ResolveRenderingItemDataSource(Rendering rendering)
{
if (rendering.DataSource != null && rendering.DataSource.StartsWith("query:"))
{
string query = rendering.DataSource.Substring("query:".Length);
Item contextItem = Context.Item;
Item queryItem = contextItem.Axes.SelectSingleItem(query);
if (queryItem != null)
{
rendering.DataSource = queryItem.Paths.FullPath;
}
}
}
}
}
Please remember that this code is not tested properly and may not work out of the box in your environment. Anyway I hope it will give you at least a good indication where to start.
I am trying to use the ZipFiles() utility method and its producing an empty zip file. I am using Sitecore 6.5. There are no error, permissions or otherwise.
Any thoughts? Here is the code.
public void CreateZipFile(string zipfileName, List<string> files)
{
var zipfile = string.Format("{0}/{1}/{2}", TempFolder.Folder, "myfolder", zipfileName) ;
var fileArray = files.ToArray();
var x = FileUtil.ZipFiles(zipfile, fileArray);
}
EDIT:
I am passing the files like this
var files = new List<string> { FileUtil.MapPath("/temp/sample.xlf") };
The proper usage of FileUtil.ZipFiles method is:
FileUtil.ZipFiles("/test.zip", new []{"/web.config", "/otherfile.txt"})
Sitecore automatically maps paths. The zip file will be created in your web app root.
EDIT AFTER COMMENT
If you want to create a zip file outside the web root and with a flat structure inside, you can use Sitecore ZipWriter class like this:
public static string ZipFiles(string absolutePathToZipfile, string[] files)
{
using (ZipWriter zipWriter = new ZipWriter(absolutePathToZipfile))
{
foreach (string path in files)
{
using (FileStream fileStream = System.IO.File.OpenRead(path.StartsWith("/") ? FileUtil.MapPath(path) : path))
zipWriter.AddEntry(FileUtil.GetFileName(path), fileStream);
}
}
return absolutePathToZipfile;
}
i downloaded the last version of iTextSharp dll. I generated a PdfPTable object and i have to set it's height. Despite to set width of PdfPTable, im not able to set height of it. Some authors suggest to use 'setFixedHeight' method. But the last version of iTextSharp.dll has not method as 'setFixedHeight'. It's version is 5.5.2. How can i do it?
Setting a table's height doesn't make sense once you start thinking about it. Or, it makes sense but leaves many questions unanswered or unanswerable. For instance, if you set a two row table to a height of 500, does that mean that each cell get's 250 for a height? What if a large image gets put in the first row, should the table automatically respond by splitting 400/100? Then what about large content in both rows, should it squish those? Each of these scenarios produces different results that make knowing what a table will actually do unreliable. If you look at the HTML spec you'll see that they don't even allow setting a fixed height for tables.
However, there's a simple solution and that's just setting the fixed height of the cells themselves. As long as you aren't using new PdfPCell() you can just set DefaultCell.FixedHeight to whatever you want.
var t = new PdfPTable(2);
t.DefaultCell.FixedHeight = 100f;
t.AddCell("Hello");
t.AddCell("World");
t.AddCell("Hello");
t.AddCell("World");
doc.Add(t);
If you are manually creating cells then you need to set the FixedHeight on each:
var t = new PdfPTable(2);
for(var i=0;i<4;i++){
var c = new PdfPCell(new Phrase("Hello"));
c.FixedHeight = 75f;
t.AddCell(c);
}
doc.Add(t);
However, if you want normal table-ness and must set a fixed height that chops things that don't fit you can also use a ColumnText. I wouldn't recommend this but you might have a case for it. The code below will only show six rows.
var ct = new ColumnText(writer.DirectContent);
ct.SetSimpleColumn(100, 100, 200, 200);
var t = new PdfPTable(2);
for(var i=0;i<100;i++){
t.AddCell(i.ToString());
}
ct.AddElement(t);
ct.Go();
you can use any one of following
cell.MinimumHeight = 20f;
or
cell.FixedHeight = 30f;
The premise is that you have downloaded the jar iText jar,you can try this code,you can achive this function,In a A4 paper out a row of three columns of dataeg:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;
public class ceshi {
public static final String DEST = "D:\\fixed_height_cell.pdf";
public static void main(String[] args) throws IOException,
DocumentException {
File file = new File(DEST);
file.getParentFile().mkdirs();
new ceshi().createPdf(DEST);
}
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
PdfPTable table = new PdfPTable(3);// Set a row and the three column of
// A4 paper
table.setWidthPercentage(100);
PdfPCell cell;
for (int r = 1; r <= 2; r++) {// Set display two lines
for (int c = 1; c <= 3; c++) {// Set to display a row of three columns
cell = new PdfPCell();
cell.addElement(new Paragraph("test"));
cell.setFixedHeight(285);// Control the fixed height of each cell
table.addCell(cell);
}
}
document.add(table);
document.close();
}
}
The front end (html and css) is set up such a way that for the description text from a Sitecore content field needs to have a <p> tag wrapped around it.
So by default the RTE wraps texts in a <p> tag = TRUE. BUT the catch is you will need to hit Enter or copy/paste multiple paragraphs.
How can we force Sitecore to add a P tag if it's just one line?
Fortunately, From the dll, one particular function caught my eye:
protected virtual void SetupScripts()
{
foreach (XmlNode node in Factory.GetConfigNodes("clientscripts/htmleditor/script"))
this.Result.Scripts.AppendFormat("<script src=\"{0}\" language=\"{1}\"></script>\n", (object) XmlUtil.GetAttribute("src", node), (object) XmlUtil.GetAttribute("language", node));
}
NICE, eh? The developers of SITECORE are clever after all.
So I did this in the web.config,
<!— CLIENT SCRIPTS
These script files are included in the client, e.g. '<script src="/myscript.js" language="JavaScript"/>'
—>
<clientscripts>
<everypage />
<htmleditor>
<script src=”/assets/js/CustomRTE.js” language=”javascript”/>
</htmleditor>
</clientscripts>
And overrode scSendRequest function from EditorWindow.aspx.
window.scSendRequest = function(evt, command) {
var editor = scRichText.getEditor();
if (editor.get_mode() == 2) { //If in HTML edit mode
editor.set_mode(1); //Set mode to Design
}
var htmls = editor.get_html(true);
var regex = /<p[^>]*>.*?<\/p>/i;
var match = regex.exec(htmls);
if(match == null && htmls != null) {
htmls = "<p>" + htmls + "</p>";
}
//$("EditorValue").value = editor.get_html(true);
$("EditorValue").value = htmls;
scForm.browser.clearEvent(evt);
scForm.postRequest("", "", "", command);
return false;
}
AND YAY .. double rainbow and unicorn.
You could create your own custom solution for this requirement as well.
You could create a new pipeline event in the
<saveRichTextContent> pipeline - This could enable you to append the tag when you hit save on the rich text editor in sitecore
<renderField> pipeline - This could on the fly wrap your text into <p></p> tags while rendering the page, if the tag was not there in the original rtf text.
If you go for method 1: <saveRichTextContent>
You could add to the pipeline in web.config:
<processor type="Sitecore72.Classes.WrapRichTextInParagraphOnSave, Sitecore72" />
And you could use the following corresponding code:
namespace Sitecore72.Classes
{
public class WrapRichTextInParagraphOnSave
{
public void Process(SaveRichTextContentArgs args)
{
if (!(args.Content.Trim().StartsWith("<p>") && args.Content.Trim().EndsWith("</p>")))
args.Content = "<p>" + args.Content + "</p>";
}
}
}
Please note, that this pipeline gets triggered only when you use the Show Editor buttong of a rich text field:
If you go for method 2: <renderField>
To append to this pipeline you would use this config:
<processor type="Sitecore72.Classes.WrapRichTextInParagraphOnRender, Sitecore72" />
And you could use the following corresponding code:
namespace Sitecore72.Classes
{
public class WrapRichTextInParagraphOnRender
{
public void Process(RenderFieldArgs args)
{
if (args.FieldTypeKey == "rich text" && !(args.Result.FirstPart.Trim().StartsWith("<p>") && args.Result.FirstPart.Trim().EndsWith("</p>")))
args.Result.FirstPart = "<p>" + args.Result.FirstPart + "</p>";
}
}
}
For both these, ensure you add reference to Sitecore.Kernel.dll and HtmlAgilityPack.dll. Both of these are available with the sitecore package solution.